将 "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**
与.
如果只是作为一个学习实验,这很好。我认为实际上不应该使用它。您通常不需要直接调用 Python 的魔术方法。
您确实想在 finally
块中调用 __exit__
。您要提供给 __exit__
的三个参数可以通过调用 sys.exc_info
.
获得
import sys
o = obj.__enter__()
try:
do_something()
finally:
obj.__exit__(*sys.exc_info())
根据引入上下文管理器的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__
,如果它 returns True
. ,这可以防止调用代码看到它
-
finally
块确保 __exit__
只被调用一次。即,如果没有引发异常,我们想调用它,但如果第一次调用通过返回 True
吞下异常或引发异常本身,则不会再次调用它。
我想知道 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**
与.
如果只是作为一个学习实验,这很好。我认为实际上不应该使用它。您通常不需要直接调用 Python 的魔术方法。
您确实想在 finally
块中调用 __exit__
。您要提供给 __exit__
的三个参数可以通过调用 sys.exc_info
.
import sys
o = obj.__enter__()
try:
do_something()
finally:
obj.__exit__(*sys.exc_info())
根据引入上下文管理器的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__
,如果它 returnsTrue
. ,这可以防止调用代码看到它
-
finally
块确保__exit__
只被调用一次。即,如果没有引发异常,我们想调用它,但如果第一次调用通过返回True
吞下异常或引发异常本身,则不会再次调用它。