【问题标题】:Is it safe to open a file, write to it and NOT close it?打开文件,写入文件而不关闭文件是否安全?
【发布时间】:2016-09-10 03:05:48
【问题描述】:

我正在尝试优化一个相当大的 Python(3) 脚本。
据我了解,当您使用 with open(..., ...) as x 时,不要需要在“with”块的末尾使用 .close()(它会自动关闭)。

我也知道您应该在完成文件操作后添加.close()(如果您不使用with),如下所示:

f = open(..., ...)
f.write()
f.close()

为了将 3 行(上图)推入 1 行,我试图改变这一点:

with open(location, mode) as packageFile:
    packageFile.write()

进入这个:

open(location, mode).write(content).close()

不幸的是,这不起作用,我收到了这个错误:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    one.save("one.txt", sample)
  File "/home/nwp/Desktop/Python/test/src/one.py", line 303, in save
    open(location, mode).write(content).close()
AttributeError: 'int' object has no attribute 'close'

当我像这样删除 .close() 时,同一行工作正常:

open(location, mode).write(content)

为什么open(location, mode).write(content).close() 不起作用,省略.close() 函数是否安全?

【问题讨论】:

  • 您不能通过将多行“推”在一起来“优化”脚本。你最终会做的只是影响可读性,可能会引入这样的错误,并使你的脚本更难维护。 应该像机器一样阅读程序,它们需要维护,而不是总是由原作者维护。当你试图把东西塞在一起时,它只会让一切变得更加困难。当然,方法链有时很有用,因为它可以防止创建可能代价高昂的临时变量,但从长远来看并不总是值得的。

标签: python file python-3.x


【解决方案1】:

我也知道您应该在完成文件操作后添加.close()

如果您使用的是with,则不会。

为什么open(location, mode).write(content).close() 不工作

因为您不是尝试关闭文件,而是尝试关闭write 方法调用的返回值,它是一个整数。你不能关闭一个整数。

省略.close() 函数是否安全?

没有。如果您曾经在不同的 Python 实现上运行此代码,或者如果 CPython 曾经放弃引用计数,您的写入可能会被任意延迟甚至完全丢失。

如果你真的想把它塞进一行,你可以写一个单行的with 语句:

with open(location, mode) as packageFile: packageFile.write(whatever)

不鼓励这样做,但比依靠文件对象的终结器为您关闭文件要少得多。

【讨论】:

  • @Tommy:不同的 Python 版本。
  • OP 标记为 'python' 和 'python3',并且他们没有在问题中指定任何地方,所以这应该更通用,或者应该为未来的用户编辑问题,也许。
  • @Tommy:我会考虑使用 Python 3 标记来指定它们在 Python 3 上,并且错误消息明确表示它们正在尝试关闭整数。无论如何,如果您使用的是 Python 2 并且最终尝试关闭 None,那么答案并没有根本不同。
  • 在你回答之前,我花了很多时间试图找出错误消息的来源,因为我无法重现它,直到你说它们在 python3 上才意识到这一点。第一个标签是 python。
【解决方案2】:

这是因为.(点)运算符从左到右工作。在a.b 中,b 是传递给a 的消息(方法调用)。说

a.b.c...

读取

do b in a and return r1, then
do c in r1 and return r2, then
...

现在open 返回一个响应read 消息的对象,但read 返回一个没有方法closestr/bytes

Bdw,总是在这种情况下使用上下文管理器,即with。而且我想知道这与优化有什么关系,正如您所说的那样,您在优化脚本时正在这样做。

【讨论】:

    【解决方案3】:

    在我看来,目标是让一个功能接连发生,但这不是这里发生的事情。

    open(location, mode) 返回一个文件: https://docs.python.org/2/library/functions.html#open

    在语法中

    open(location, mode).write(content)
    

    这实际上等价于

    file = open(location, mode)
    file.write(content)
    

    open 语句变成了一个类型文件,它有一个名为 write() 的函数。 .close() 不起作用的原因是 file.write() 没有名为 close() 的函数。这是试图做的是file.function().function()。

    在任何情况下尝试通过减少行数来优化代码都不会显着提高性能,正常的 with 语句应该同样快。除非你想去打代码打高尔夫球,这完全是另外一回事。

    祝你有美好的一天!

    【讨论】:

    • 感谢您的回答。你知道你可以用````引用你的内联代码,比如file.write()吗? OP还询问省略close()是否安全。
    【解决方案4】:

    省略 .close() 函数是否安全?

    在当前版本的 CPython 中,文件将在 for 循环结束时关闭,因为 CPython 使用引用计数作为其主要的垃圾收集机制,但这是一个实现细节,而不是该语言的特性。

    也可以直接引用user2357112:if you ever run this code on a different Python implementation, or if CPython ever abandons reference counting, your write could be arbitrarily delayed or even lost completely.

    为什么 open(location, mode).write(content).close() 不起作用?

    这是因为我试图在 open(location, mode).write(content) 返回时调用 .close() 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2015-01-11
      • 1970-01-01
      相关资源
      最近更新 更多