with 语句的等效 try 语句是什么? [英] What is the equivalent try statement of the with statement?
问题描述
阅读with
后Python 语言文档的声明部分,我想知道声明此 Python 代码是否正确:
After reading the with
statement section of the language documentation of Python, I was wondering if it is correct to state that this Python code:
with EXPRESSION as TARGET:
SUITE
相当于这个:
try:
manager = (EXPRESSION)
value = manager.__enter__()
TARGET = value # only if `as TARGET` is present in the with statement
SUITE
except:
import sys
if not manager.__exit__(*sys.exc_info()):
raise
else:
manager.__exit__(None, None, None)
编辑
正确的等效 Python 代码(真正的 CPython 实现是用 C 语言实现的)实际上是由 Guido van Rossum 本人在 PEP 343:
mgr = (EXPR)
exit = type(mgr).__exit__ # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
try:
VAR = value # Only if "as VAR" is present
BLOCK
except:
# The exceptional case is handled here
exc = False
if not exit(mgr, *sys.exc_info()):
raise
# The exception is swallowed if exit() returns true
finally:
# The normal and non-local-goto cases are handled here
if exc:
exit(mgr, None, None, None)
自 Python 3.6 以来,这已经发生了一些变化:现在 __enter__
函数被加载之前 __exit__
函数(参见 https://bugs.python.org/issue27100).
Since Python 3.6, this has changed a little: now the __enter__
function is loaded before the __exit__
function (cf. https://bugs.python.org/issue27100).
所以我的等效 Python 代码有三个缺陷:
So my equivalent Python code had three flaws:
__enter__
和__exit__
函数应该在调用__enter__
函数之前加载.__enter__
函数应该在try
语句之外调用(参见语言文档中第 4 点的注释).else
子句应该改为finally
子句,以处理存在非本地 goto 语句 (break
,continue
,return
) 在suite
中.
- The
__enter__
and__exit__
functions should be loaded before calling the__enter__
function. - The
__enter__
function should be called outside thetry
statement (cf. the note of point 4 in the language documentation). - The
else
clause should instead be afinally
clause, to handle the case when there is a non-local goto statement (break
,continue
,return
) insuite
.
但是我不明白为什么 PEP 343 中的等效 Python 代码将 finally
子句放在外部 try
语句中而不是内部 语句中>try
语句?
However I don’t understand why the equivalent Python code in PEP 343 puts the finally
clause in an outer try
statement instead of in the inner try
statement?
推荐答案
Nick Coghlan,PEP 343,在 Python 错误跟踪器上回答:
Nick Coghlan, the other author of PEP 343, answered on the Python bug tracker:
这是一个历史时间问题:PEP 343 是在之前编写的try/except/finally 被允许,当 try/finally 和 try/except 被允许时仍然不同的陈述.
It's a matter of historical timing: PEP 343 was written before try/except/finally was allowed, when try/finally and try/except were still distinct statements.
然而,PEP 341也被 Python 2.5 接受并实现,允许现代的 try/except/finally 形式:https://docs.python.org/dev/whatsnew/2.5.html#pep-341-unified-try-except-finally
However, PEP 341 was also accepted and implemented for Python 2.5, allowing for the modern try/except/finally form: https://docs.python.org/dev/whatsnew/2.5.html#pep-341-unified-try-except-finally
所以现代 try
语句等效于 with
语句的 Python 代码是这样的:
So the modern try
statement equivalent Python code of the with
statement is this one:
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value # only if `as TARGET` is present in the with statement
SUITE
except:
import sys
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
这篇关于with 语句的等效 try 语句是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!