23

我似乎记得在程序中多次打开文件可能会导致共享查找指针的低级语言的情况。通过在 Python 中搞乱一点,这对我来说似乎没有发生:

$ cat file.txt
first line!
second
third
fourth
and fifth
>>> f1 = open('file.txt')
>>> f2 = open('file.txt')
>>> f1.readline()
'first line!\n'
>>> f2.read()
'first line!\nsecond\nthird\nfourth\nand fifth\n'
>>> f1.readline()
'second\n'
>>> f2.read()
''
>>> f2.seek(0)
>>> f1.readline()
'third\n'

这种行为是否安全?我很难找到一个说没关系的消息来源,如果我能依赖这个,那会很有帮助。

我没有将位置视为文件对象的属性,否则我对此更有信心。我知道它可以在迭代器内部保存,但不知道 .tell() 在这种情况下如何得到它。

>>> dir(f1)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__',
 '__init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__',
 '__setattr__', '__str__', 'close', 'closed', 'encoding', 'fileno', 'flush',
 'isatty', 'mode', 'name', 'newlines', 'next', 'read', 'readinto', 'readline',
 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writelines',
 'xreadlines']

更新在Python Essential Reference
的第 161 页上,它指出

同一个文件可以在同一个程序(或不同程序)中多次打开。打开文件的每个实例都有自己的文件指针,可以独立操作。

所以它实际上似乎是安全的、明确的行为

4

1 回答 1

15

在现代操作系统上(1969 年后的类 UNIX 操作系统,或 2000 年后的 Windows,可能在此之前,但我将 Win2K 视为第一个“现代”Windows),打开文件的每个实例(文件描述符)有自己的查找指针。Python 的类中没有魔法file可以导致实例共享状态;file是一个普通C文件句柄的包装器,它本身封装了一个OS文件描述符,以及对应的C函数的实现file.tell()和调用。(有关混乱的细节,请参阅 CPython 的。)C 库行为和底层操作系统的行为之间可能存在差异,但在这种特殊情况下,这不是一个因素。file.seek()stdiofileobject.c

如果您使用 IronPython 或 Jython,它将使用标准 .Net 或 Java 文件对象作为其底层实现,而后者又将使用标准 C 库或 OS 实现。

所以你的方法很好,除非你以某种方式在一些具有奇怪 I/O 行为的非标准操作系统上运行 Python。

如果不及时刷新,可能会在写的时候得到意想不到的结果;数据在实际到达磁盘之前可能会在内存中停留一段时间,并且可供您在同一文件上打开的其他文件描述符使用。正如 abarnert 在评论中指出的那样,这无论如何都是有问题的,除非在非常简单的情况下。

于 2013-01-24T21:01:23.727 回答