Это было обсуждено на 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
Есть ли какие-либо риски с выполнением этого?
Один значительный риск заключается в том, что после открытия файла процесс обращается с этим файлом по его файловому дескриптору, не его пути. Во многих операционных системах путь к файлу может быть изменен другим процессом (например, операцией mv
в несвязанном процессе), и дескриптор файла по-прежнему действителен и относится к тот же файл.
Я часто пользуюсь этим, например, начинаю загрузку большого файла, затем понимаю, что целевой файл находится не там, где я хочу, и перехожу в отдельную оболочку и перемещаю ее в нужное место. - пока загрузка продолжается без прерывания.
Таким образом, это плохая идея - полагаться на то, что путь остается неизменным на протяжении всего жизненного цикла процесса, когда операционная система не дает такой гарантии.
Это зависит от того, что вам это нужно для.
Пока вы понимаете ограничения - кто-то может переместить, переименовать или жестко связать файл между собой - для этого есть множество подходящих применений. Вы можете удалить файл, когда закончите с ним или если что-то пойдет не так во время его записи (например,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 ...)