关闭文件的好方法

时间:2014-06-28 02:49:10

标签: python

我们说,我们有以下代码:

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)

请注意,这是一个演示代码。实际程序要复杂得多。

现在,当我退出程序时,如何知道我是否安全地关闭了所有打开的文件?此时我只是假设文件已经关闭。目前我的程序工作正常,但我希望它们健壮,没有与未正确关闭的文件相关的问题。

3 个答案:

答案 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)