This question already has answers here:
Is explicitly closing files important?
(6个答案)
5年前关闭。
我正在阅读Zed Shaw关于Python的书。
有一个练习要求以最少的行数实现从一个文件到另一个文件的复制。我在一行中做到了,就是这样:
(open(argv[2], 'w')).write(open(argv[1]).read())
我的问题是,如果我这样做,会发生什么最坏的事情?我的意思是不关闭它们。
我用另一种方法做了同样的事情,教程说这是更可靠的方法。你怎么看?
with open(argv[1], 'r') as source:
with open(argv[2], 'w') as dest:
dest.write(source.read())
我是新来者,这类问题看似愚蠢,但对我来说很重要。
感谢您的关注。缺口
python大神给出的解决方案
实际上,在大多数最新的Python实现中,文件对象一旦被取消引用就关闭文件,因为垃圾回收主要是通过引用计数来完成的。
但是,Python语言不能保证:您依赖于实现细节。
因此,单行将打破当前或将来使用更高级垃圾收集技术的Python实现(例如,将GC委派给底层JVM或.Net运行时)。
with
保证在块退出后立即关闭-在该语言的任何正确实现中。因此,它绝对更健壮且防错。
此外,假设存在以argv[2]
命名的文件,但是没有以arg[1]
命名的文件。单线:
(open(argv[2], 'w')).write(open(argv[1]).read())
您首先打开要写入的文件(从而清除其内容)-带有多余的括号BTW,但是它们无害:-)。然后在您尝试打开要读取的文件,遇到异常并失败的情况下-但是您打开的第一个文件仍然被清除掉了(即在磁盘上留空)。在这种情况下,这不太可能是所需的行为。
在with
变体中,您首先尝试打开要读取的文件-如果失败,则从不擦除要写入的文件。这对我来说也感觉更健壮-这适用于Python的任何版本,过去,现在或将来:-)。
而且,还有一件事:我想知道规范是否断言文件内容适合内存。如果没有,尝试一次吞咽读取文件将因内存错误而失败-而是,您希望一次循环读取和写入一些大但有界的BUFFER_SIZE
字节。这强调了出于复制目的,最好以二进制而不是文本模式打开文件(文本模式是默认模式,因此它在代码中使用,如无其他说明)。从这个角度来看,更强大的是:
with open(argv[1], 'rb') as source:
with open(argv[2], 'wb') as dest:
while True:
buf = source.read(BUFFER_SIZE)
if not buf: breal
dest.write(buf)
有趣的是,仅复制一个文件会有多少个小细节会出错,嗯?-)这就是为什么Python幸福的关键是学习Python的大型标准库,该库包含经过精心编码的模块,以照顾可能出现的所有各种情况。即使是最简单的任务。
这个问题的真正答案(我面试一个声称掌握Python的求职者时给了A +)是(鼓声……):
import shutil
shutil.copy2(argv[1], argv[2])
!-)参见https://docs.python.org/2/library/shutil.html#shutil.copy2处的文档(以及同一模块中copy
和copystat
函数的上方):这可以安全可靠地复制“权限位,最后访问时间,最后修改时间和标志” ...还有更多值得一提的文件复制,shutil
代表您来处理。
学习Python标准库至少与学习语言本身一样重要!-)