文件对象的绝对路径

14 投票
2 回答
15037 浏览
提问于 2025-04-15 20:30

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

这样做有没有什么风险呢?

2 个回答

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一个丑陋且不一致的怪癖……)

14

一个很大的风险是,一旦文件被打开,程序是通过文件描述符来处理这个文件的,而不是通过它的路径。在很多操作系统中,文件的路径可能会被其他进程改变(比如说,另一个进程执行了一个mv操作),而文件描述符仍然有效,并且指向同一个文件。

我经常利用这一点,比如说,我开始下载一个大文件,然后意识到目标文件的位置不对,这时我可以打开一个新的命令行窗口,把文件移动到正确的位置——而下载过程不会受到影响。

所以,依赖路径在整个进程生命周期内保持不变是个坏主意,因为操作系统并没有提供这样的保证。

撰写回答