Python open()追加和读取,file.read()返回空字符串

时间:2015-08-03 18:29:25

标签: python file python-3.x file-io

read()模式下打开的文件上尝试调用a+时发现奇怪的行为(Python 3.4.1)

如此处所见
File mode for creating+reading+appending+binary
可以在读取/追加模式打开文件

然而
这段代码:

with open("hgrc", "a+") as hgrc:
            contents=hgrc.read()

返回contents={str}''。根据上面发布的答案,这是出乎意料的。
现在,以下代码

with open("hgrc", "r+") as hgrc:
            contents=hgrc.read()

返回contents={str}'contents of hgrc.....',这是预期的,但不会为我们提供附加到文件的选项。

根据规格

https://docs.python.org/2/library/functions.html#open

Modes 'r+', 'w+' and 'a+' open the file for updating (reading and writing); note that 'w+' truncates the file. Append 'b' to the mode to open the file in binary mode, on systems that differentiate between binary and text files; on systems that don’t have this distinction, adding the 'b' has no effect.

这意味着
当我们以a+模式打开文件时,我们应该可以在其上调用read()并获取文件的内容,对吗? 思考?意见?等??

2 个答案:

答案 0 :(得分:5)

a+在末尾打开文件以进行追加。如果您想要读取其内容,则需要在其上调用.seek(0),但此时您也可以使用r+,因为这会在开始时打开文件。

答案 1 :(得分:3)

这是Python 2与Python 3的问题。

带有open()

a+在两个Python版本中表现不同。 (注意:您显示您正在使用Python 3.4.1 ,但是您引用了Python 2 的文档!)

(事实上,您正在寻找的行为(在“这意味着”中)与Python 2一样。我认为他们改变了行为,因为“追加”意味着“文件指针”在文件的末尾“给许多人。”

让我们用Python3测试...

$ python3
Python 3.4.3 (default, Jul 28 2015, 18:20:59) 
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> lic = open('LICENSE', 'a+')
>>> lic.read()
''
>>> # Hmmm, no content? EOF, obviously. Let's reset the file pointer ...
>>> lic.seek(0)
0
>>> lic.read()
'Apache License\nVersion 2.0, January 2004\n...'

与Python2相同......

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> lic = open('LICENSE', 'a+')
>>> lic.read()
'Apache License\nVersion 2.0, January 2004\n...'
>>> lic.seek(0)
>>> lic.read()
'Apache License\nVersion 2.0, January 2004\n...'

结论:在使用seek(0)打开文件后,使用a+ 始终是安全的,无论您使用哪个Python版本。这似乎是a+模式特有的。

为什么系统调用在两个Python版本中表现不同?

有人会认为文件操作是系统调用,因此它由操作系统处理。这与Python不同,因为它看起来像Python documentation

  

注意: Python不依赖于底层操作系统的文本文件概念;所有处理都由Python本身完成,因此与平台无关。

BTW,这个行为在Python bug跟踪器上已经reported as a bug