Полный путь объекта файла

Это было обсуждено на StackOverflow прежде - я пытаюсь найти хороший способ найти полный путь объекта файла, но мне нужен он, чтобы быть устойчивым к os.chdir(), так не может использовать

f = file('test')
os.path.abspath(f.name)

Вместо этого я задавался вопросом, является ли следующее хорошим решением - в основном расширение класса файла так, чтобы на открытии, полный путь файла был сохранен:

class File(file):

    def __init__(self, filename, *args, **kwargs):
        self.abspath = os.path.abspath(filename)
        file.__init__(self, filename, *args, **kwargs)

Затем можно сделать

f = File('test','rb')
os.chdir('some_directory')
f.abspath # absolute path can be accessed like this

Есть ли какие-либо риски с выполнением этого?

14
задан bignose 16 May 2014 в 00:04
поделиться

2 ответа

Один значительный риск заключается в том, что после открытия файла процесс обращается с этим файлом по его файловому дескриптору, не его пути. Во многих операционных системах путь к файлу может быть изменен другим процессом (например, операцией mv в несвязанном процессе), и дескриптор файла по-прежнему действителен и относится к тот же файл.

Я часто пользуюсь этим, например, начинаю загрузку большого файла, затем понимаю, что целевой файл находится не там, где я хочу, и перехожу в отдельную оболочку и перемещаю ее в нужное место. - пока загрузка продолжается без прерывания.

Таким образом, это плохая идея - полагаться на то, что путь остается неизменным на протяжении всего жизненного цикла процесса, когда операционная система не дает такой гарантии.

14
ответ дан 1 December 2019 в 14:11
поделиться

Это зависит от того, что вам это нужно для.

Пока вы понимаете ограничения - кто-то может переместить, переименовать или жестко связать файл между собой - для этого есть множество подходящих применений. Вы можете удалить файл, когда закончите с ним или если что-то пойдет не так во время его записи (например,gcc делает это при записи файлов):

f = File(path, "w+")
try:
    ...
except:
    try:
        os.unlink(f.abspath)
    except OSError: # nothing we can do if this fails
        pass
    raise

Если вы просто хотите иметь возможность идентифицировать файл в пользовательских сообщениях, там уже есть file.name. К сожалению, это невозможно (надежно) использовать ни для чего другого; например, невозможно различить имя файла " " и sys.stdin.

(Вам действительно не нужно наследоваться от встроенного класса только для того, чтобы добавлять к нему атрибуты; это просто уродливая непоследовательная причуда Python ...)

1
ответ дан 1 December 2019 в 14:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: