3

我遇到了一些遍历文件中行的代码,如下所示:

for line in open(filename, 'r'):
    do_all_the_things()

这是一个更 Pythonic 的版本,例如:

with open(filename, 'r') as f:
    for line in f:
        do_all_the_things()

它使用更少的缩进级别,所以看起来更好,但它是一样的吗?据我所知,with基本上添加了一个finally: f.close()或一些东西来确保在离开块后清理对象。当第一个for循环结束(或者被 a 缩短break)并且变量超出范围时,是否会发生同样的事情?我可以从第一段代码中得到提示并为自己节省一些击键,或者更确切地说,我应该修复它吗?

4

2 回答 2

2

除了在 for 循环使用的迭代器中,您没有创建对文件对象的任何引用。

这意味着一旦 for 循环结束,该迭代器,然后是文件对象,它们的引用计数将归零,并且它们将被删除。

当一个文件对象被删除时,它会被关闭。

因此,您不会使用裸for循环留下打开的文件。

也就是说,在一个更大的程序中,最好是明确的——并且with声明清楚地表明该文件仅在该上下文中使用。

就个人而言,如果我打开一个文件进行写入/追加,那么with即使我只在一个地方使用它,我也会使用它。如果我只是打开它进行阅读而不是创建显式引用,我只是直接使用该对象。

于 2013-04-19T17:14:58.977 回答
1

绝对使用上下文管理器。这是保证您的文件对象得到正确处理的唯一方法。

虽然第一个版本可能不会在 Cpython 中(当前)给您带来任何问题,但该规范从未指定何时(或什至是否__del__被调用。因此,您无法确定您的文件对象是否会使用第一个版本正确完成。

于 2013-04-19T17:22:42.933 回答