在Python中,如果我在“with”块内返回,文件是否仍然closures?

考虑以下:

with open(path, mode) as f: return [line for line in f if condition] 

文件是否会被正确closures,或者使用return绕过上下文pipe理器 ?

是的,它的行为就像try块之后的finally块,即它总是执行(除非python进程以一种不寻常的方式结束)。

在PEP-343的一个例子中也提到了这一点,

 with locked(myLock): # Code here executes with myLock held. The lock is # guaranteed to be released when the block is left (even # if via return or by an uncaught exception). 

但是值得一提的是,你不能轻易地捕获open()调用抛出的exception,而不把整个块放在一个try..except块内,这通常不是我们想要的。

是。

 def example(path, mode): with open(path, mode) as f: return [line for line in f if condition] 

..几乎相当于:

 def example(path, mode): f = open(path, mode) try: return [line for line in f if condition] finally: f.close() 

更准确地说,上下文pipe理器中的__exit__方法在退出块时总是被调用(不pipeexception,返回等)。 文件对象的__exit__方法只是调用f.close() (例如在CPython中 )

更一般地说,如果从上下文中return ,那么With语句上下文pipe理器的__exit__方法确实会被调用。 这可以用以下方法进行testing:

 class Resource(object): def __enter__(self): print('Entering context.') return self def __exit__(self, *exc): print('Exiting context.') def fun(): with Resource(): print('Returning inside with-statement.') return print('Returning outside with-statement.') fun() 

输出是:

 Entering context. Returning inside with-statement. Exiting context. 

上面的输出确认__exit__被调用,尽pipe提前return 。 因此,上下文pipe理器不被绕过。