在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理器不被绕过。