在我的代码中,我需要能够正确地打开和关闭设备,从而了解使用上下文管理器的必要性。虽然上下文管理器通常被定义为具有__enter__
和__exit__
方法的类,但是似乎也有可能修饰一个用于上下文管理器的函数(请参见a recent post和another nice example here)。在
在下面的(工作)代码片段中,我实现了两种可能性;一种只需要将注释行与另一种进行交换:
import time
import contextlib
def device():
return 42
@contextlib.contextmanager
def wrap():
print("open")
yield device
print("close")
return
class Wrap(object):
def __enter__(self):
print("open")
return device
def __exit__(self, type, value, traceback):
print("close")
#with wrap() as mydevice:
with Wrap() as mydevice:
while True:
time.sleep(1)
print mydevice()
我尝试运行代码并用CTRL-C
停止它。当我在上下文管理器中使用Wrap
类时,__exit__
方法被称为expeed(文本'close'在终端中打印),但是当我用wrap
函数尝试相同的操作时,文本'close'不会打印到终端。在
我的问题是:代码片段有问题吗,我是否遗漏了什么,或者为什么没有用修饰函数调用print("close")
行?在
文档中
contextmanager
的示例有点误导性。在yield
之后的函数部分与上下文管理器协议的__exit__
并不真正对应。文档中的关键点是:因此,如果您想在contextmanager修饰函数中处理异常,则需要编写自己的
^{1}$try
来包装yield
,并自己处理异常,在finally
中执行清理代码(或者只在except
中阻止异常,并在try/except
之后执行清理)。例如:This page还显示了一个有指导意义的示例。在
相关问题 更多 >
编程相关推荐