繁体   English   中英

将“with”语句转换为“try”语句

[英]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)

一些注意事项:

  1. 我们不写o = type(mgr).__enter__(mgr)因为名称o仅在__enter__不引发异常时才定义,允许我们进入try语句。 (还有其他方法可以处理这个问题,但这就是我解释 PEP-343 翻译的方式。)
  2. __exit__可以在两个不同的地方调用。 如果我们捕获到异常,我们会将有关该异常的信息传递给__exit__ ,如果它返回True ,这可以防止调用代码看到它。
  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM