为什么os.fdopen()函数会忽略"mode"参数?

3
这段代码在 Python 2.7.16 和 3.8.3 上运行会产生不同的结果:
import tempfile
import os

fd, lockfile = tempfile.mkstemp()
flags = os.O_RDWR | os.O_CREAT
mode = 'w+b'

fd = os.open(lockfile, flags)
fileobj = os.fdopen(fd, mode)

print(fileobj.mode)

os.remove(lockfile)

在Python 2.7中,它按预期打印w+b,但在Python 3.8中,它打印了rb+。为什么会以这种方式不尊重模式参数?
我尝试手动创建一个文件来消除tempfile的差异,但仍然得到相同的结果。
我在文档中没有发现任何明显的问题: 运行于MacOS 10.14.6。

1
fd 已经代表了一个打开的文件,你无法更改模式。fdopen 只是提供了一个包装它的 Python 对象。 - chepner
从实验中我认为你可以改变模式,但你只能给它更少的权限。例如,如果你在os.open中打开一个文件进行读取,那么你就不能在os.fdopen中将其更改为可写的,但反过来是可以的。此外,回答我的问题,rb+看起来相当于wb+(至少在这个Python上下文中),因为+打开文件以进行更新(读和写)。 - Alex James
2个回答

1

从内置的open函数文档中:

mode是一个可选的字符串,指定文件打开的模式

当使用文件描述符而不是文件路径调用open(或者使用需要文件描述符的别名fdopen)时,不会打开文件。创建并返回一个包装文件描述符的Python文件对象。您无法更改已打开文件的模式,因此mode参数被简单地忽略。


我提出了一个CPython问题(https://github.com/python/cpython/issues/95498),建议将文档更新,增加有关使用文件描述符调用内置的open()函数时忽略“mode”参数的信息,因为这一点显然缺失。 - Piotr Dobrogost

0

我不确定 Python 是否追踪此信息,但是考虑到您在 os.open 中使用的 flags,我认为 rb+ 实际上是正确的。

您使用 "读/写" 和 "如果不存在就创建" 的标志调用了 os.open,但没有使用 "截断" (O_TRUNC)。这正是模式 rb+wb+ 之间的区别。假设 Python 追踪了您的 flags,那么这就是正确的模式。


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