在Python中一次打开几次文件是否安全?

Rya*_*ing 17 python file seek

我似乎回想起低级语言中的情况,即在程序中多次打开文件可能会导致共享的搜索指针.通过在Python中乱搞一下,这似乎并没有发生在我身上:

$ cat file.txt
first line!
second
third
fourth
and fifth
Run Code Online (Sandbox Code Playgroud)
>>> 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'
Run Code Online (Sandbox Code Playgroud)

这种行为是否安全?我很难找到一个消息来源说它没关系,如果我可以依赖它,它会有很大帮助.

我没有将该位置视为文件对象的属性,否则我对此更有信心.我知道它可以保存在迭代器内部,但idk如何.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']
Run Code Online (Sandbox Code Playgroud)

更新
Python基本参考的第161页上,它指出

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

所以它似乎实际上是安全的,定义的行为

kin*_*all 9

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

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

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

如果你没有及时更新,写作时可能会得到意想不到的结果; 数据可以在实际命中磁盘之前在内存中挂起一段时间,并且可用于您在同一文件上打开的其他文件描述符.正如abarnert在评论中指出的那样,无论如何这都是有问题的,除非是非常简单的情况.

  • 更重要的是,这里的大部分细节都是错误的.`file`是_not_普通文件描述符的包装器; 它是`FILE*`的包装器.并且`tell`和`seek`不直接调用相应的低级OS函数; 他们称之为相应的中级"stdio"函数.这在Windows上产生了很大的不同,因为例如文件锁定在`fopen`与`CreateFile`中的工作原理完全不同. (6认同)