文件对象的绝对路径

14

这个问题之前在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

这样做有什么风险吗?


3
一个打开的文件描述符可以有多个链接和多个绝对路径名。你是反其道而行之。为什么不先计算出路径,然后使用该绝对路径打开文件? - S.Lott
1
第一行提供一些相关的SO问题链接会很有帮助。 - demongolem
2个回答

14

一个重要的风险是,一旦文件被打开,进程将通过其文件描述符而非路径来处理该文件。许多操作系统上,文件的路径可以被其他进程更改(例如由不相关进程中的mv操作),而文件描述符仍然有效并引用同一文件。

我经常利用这一点,例如开始下载一个大文件,然后意识到目标文件不在我想要的位置,然后跳转到一个单独的 shell 并将它移动到正确的位置 - 而下载过程继续不间断地进行。

因此,依赖路径在进程的生命期内保持不变是一个坏主意 ,因为操作系统没有给出这样的保证。


1

这取决于你需要它做什么。

只要你理解了限制——有人可能会在此期间移动、重命名或硬链接文件——就有很多适当的用途。你可能想在使用完文件后将其删除,或者在写入文件时出现问题时删除它(例如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。不幸的是,这个属性不能(可靠地)用于其他任何事情;例如,无法区分文件名“<stdin>”和sys.stdin。

(你真的不应该从内置类派生来添加属性;这只是Python的一个丑陋的不一致性怪癖...)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接