with 语句的等效 try 语句是什么? [英] What is the equivalent try statement of the with statement?

查看:29
本文介绍了with 语句的等效 try 语句是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读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:

  1. __enter____exit__ 函数应该在调用 __enter__ 函数之前加载.
  2. __enter__ 函数应该在 try 语句之外调用(参见语言文档中第 4 点的注释).
  3. else 子句应该改为 finally 子句,以处理存在非本地 goto 语句 (break,continue, return) 在suite中.
  1. The __enter__ and __exit__ functions should be loaded before calling the __enter__ function.
  2. The __enter__ function should be called outside the try statement (cf. the note of point 4 in the language documentation).
  3. The else clause should instead be a finally clause, to handle the case when there is a non-local goto statement (break, continue, return) in suite.

但是我不明白为什么 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆