2013-05-13 162 views
4

声明我有这样一个功能:打开文件,并在Python

def func(filename): 
    with open(filename) as f: 
     return [line.split('\t')[0] for line in f] 

是“同向”的语句关闭文件,即使有一个“突然”函数的返回?我可以忽略“with”语句吗?即从内存泄漏的角度来看它是安全的和等效的,

def func(filename): 
    return [line.split('\t')[0] for line in open(filename)] 

回答

4

这是安全的。上下文管理器的__exit__即使在return的上下文内也被调用,因此文件句柄已正确关闭。

这里有一个简单的测试:

class ContextTest(object): 
    def __enter__(self): 
     print('Enter') 

    def __exit__(self, type, value, traceback): 
     print('Exit') 

def test(): 
    with ContextTest() as foo: 
     print('Inside') 
     return 

当你调用test(),您可以:

Enter 
Inside 
Exit 
+0

遗憾也不是那么清楚,我,我可以忽略“与”并使用第二个选择吗? – elyase 2013-05-13 01:15:58

+0

@elyase:在这两个示例中都没有内存泄漏,但是您没有明确地关闭第二个文件句柄,这可能会导致问题:http://stackoverflow.com/questions/4599980/python-close-file -descriptor-question – Blender 2013-05-13 01:18:22

+0

很好的例子!你可能想把'... as test'改成其他的东西,它使我停了一下,因为你的函数名也是测试。 – monkut 2013-05-13 01:28:14

0

保障这安全实际上是with...as...语法的全部目的;它将取代try/finally区块,否则会相当尴尬。所以是的,它保证是安全的,这就是为什么我更喜欢with open as ff = open

请参阅http://effbot.org/zone/python-with-statement.htm了解语法为什么存在以及它是如何工作的。请注意,您可以使用__enter____exit__方法编写自己的类,以充分利用此语法。

另请参见PEP此功能:http://www.python.org/dev/peps/pep-0343/