[英]Convert “with” statement to “try” statement
我想知道with
语句是如何工作的。 我正在尝试转换以下内容:
with obj() as o:
do_something()
进入这个:
o = obj.__enter__()
try:
do_something()
except Exception as e:
obj.__exit__(type(e),e, **I don't know what should be here**)
else:
obj.__exit__(None, None , None)
那么会怎么样呢? 如果我在任何地方错了,请纠正我。 我想知道换什么
**I don't know what should be here**
。
根据引入上下文管理器的PEP-343 ,代码
with obj() as o:
do_something()
相当于
mgr = obj()
exit = type(mgr).__exit__
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
o = value
do_something()
except:
exc = False
if not exit(mgr, *sys.exc_info()):
raise
finally:
if exc:
exit(mgr, None, None, None)
一些注意事项:
o = type(mgr).__enter__(mgr)
因为名称o
仅在__enter__
不引发异常时才定义,允许我们进入try
语句。 (还有其他方法可以处理这个问题,但这就是我解释 PEP-343 翻译的方式。)__exit__
可以在两个不同的地方调用。 如果我们捕获到异常,我们会将有关该异常的信息传递给__exit__
,如果它返回True
,这可以防止调用代码看到它。finally
块确保__exit__
被调用一次。 也就是说,如果没有引发异常,我们希望调用它,但如果第一次调用通过返回True
吞下异常或引发异常本身,则不会再次调用它。如果只是作为一个学习实验,这很好。 我认为它实际上不应该被使用。 您通常不需要直接调用 Python 的魔法方法。
你真的想在finally
块中调用__exit__
。 要提供给__exit__
的三个 arguments 可以通过调用sys.exc_info
获得。
import sys
o = obj.__enter__()
try:
do_something()
finally:
obj.__exit__(*sys.exc_info())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.