我们说,我们有以下代码:
from sys import exit
def parseLine(l):
if '#' not in l:
print 'Invalid expresseion'
exit(1)
return l
with open('somefile.txt') as f:
for l in f:
print parseLine(l)
(请注意,这是一个演示代码。实际程序要复杂得多。)
现在,当我退出程序时,如何知道我是否安全地关闭了所有打开的文件?此时我只是假设文件已经关闭。目前我的程序工作正常,但我希望它们健壮,没有与未正确关闭的文件相关的问题。
答案 0 :(得分:7)
with
阻止文件的一个主要好处是它会自动关闭文件,即使有例外。
https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects
答案 1 :(得分:3)
它已经正常关闭,因为您在打开文件时使用了with
语句。即使存在异常,当控件离开with
语句时,它也会自动关闭文件。这通常被认为是确保文件在应该关闭时的最佳方式。
如果您自己不使用with
语句或close
文件,则会有一些内置安全措施和一些陷阱。
首先,在CPython中,文件对象的析构函数将在垃圾收集时关闭文件。但是,这并不能保证在其他Python实现中发生,即使在CPython中,也不能保证及时发生。
其次,当您的程序退出时,操作系统将关闭程序保持打开的所有文件。这意味着如果您不小心做了一些使程序永远不会关闭其文件的东西(可能您必须发出kill -9
或其他阻止清理代码运行的东西),您不必重新启动计算机或执行文件系统修复以使文件再次可用。但是,依靠这个作为关闭文件的常用方法是不可取的。
答案 2 :(得分:1)
如果您正在使用with
阻止,那么您基本上会在open
阻止内部进行try
次呼叫,而close
进入finally
阻止。有关官方文档的更多信息,请参阅https://docs.python.org/2/tutorial/inputoutput.html。
由于调用exit()实际上会引发SystemExit异常,因此finally
块中的所有代码将在程序完全退出之前运行。由于是这种情况,并且由于您使用了with open(...)
块,因此该文件将以任何未捕获的异常关闭。
以下是您的代码( http://python.dbgr.cc/s 的runnable / debuggable / steppable)
from sys import exit
def parseLine(l):
if '#' not in l:
print 'Invalid expresseion'
exit(1)
return l
with open('somefile.txt') as f:
for l in f:
print parseLine(l)
print("file is closed? %r" % f.closed)
不使用with open(...)
块的等效代码如下所示( http://python.dbgr.cc/g 的runnable / debuggable):
from sys import exit
def parseLine(l):
if '#' not in l:
print 'Invalid expresseion'
exit(1)
return l
try:
f = open('somefile.txt')
for l in f:
print parseLine(l)
finally:
print("Closing open file!")
f.close()
print("file is closed? %r" % f.closed)