【问题标题】:Python open() append and read, file.read() returns empty stringPython open() 追加读取,file.read() 返回空字符串
【发布时间】:2015-10-25 23:21:32
【问题描述】:

在尝试对以 a+ 模式 (Python 3.4.1) 打开的文件调用 read() 时发现一个奇怪的行为

如图所示
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 filein binary mode, on systems that differentiate between binary and textfiles; on systems that don’t have this distinction, adding the 'b' has noeffect.

这意味着
当我们以a+ 模式打开一个文件时,我们应该能够在它上面调用read() 并取回文件的内容,对吗? 想法?意见?等等??

【问题讨论】:

  • 看看我的answer here 是否有帮助。它在 C 线程上,但它也应该适用
  • 这有助于真正记住单击按钮 (;

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


【解决方案1】:

这是一个 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...'

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


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

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

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

顺便说一句,此行为已在 Python 错误跟踪器上显示为 reported as a bug

【讨论】:

    【解决方案2】:

    a+ 在末尾打开文件以进行追加。如果你想读入它的内容,你需要调用.seek(0),但此时你最好只使用r+,因为这会在开始时打开文件。

    【讨论】:

    • .seek(0) 有效。我希望能够打开文件以追加并有条件地追加一行到该文件,如果它还没有包含该行。或者,如果我只是需要阅读,我可以像“r”一样简单。完美的。谢谢!
    • 请注意,这仅适用于 Python 3。在 Python 2 中,a+ 打开文件以进行追加,并回退文件指针。当然,.seek(0) 在 Python 2 中没有任何害处,但并非绝对需要。
    • @Peterino 我不知道,我很少使用 2.x。很高兴知道,谢谢!
    • seek 对我不起作用。仍然返回空字符串。我差点把桌子翻了
    猜你喜欢
    • 2012-10-14
    • 2011-07-23
    • 1970-01-01
    • 2011-12-24
    • 2018-05-25
    • 1970-01-01
    • 2016-04-07
    • 1970-01-01
    • 2017-06-14
    相关资源
    最近更新 更多