gpt4 book ai didi

python - 为什么在 except 子句中使用 `or` 不会导致 SyntaxError?它有有效的用途吗?

转载 作者:行者123 更新时间:2023-12-04 02:20:26 25 4
gpt4 key购买 nike

在工作中,我偶然发现了一个 except带有 or 的条款运算符(operator):

try:
# Do something.
except IndexError or KeyError:
# ErrorHandling

我知道异常类应该作为元组传递,但它让我烦恼的是它甚至不会导致 SyntaxError .

所以首先我想调查它是否真的有效。而事实并非如此。

>>> def with_or_raise(exc):
... try:
... raise exc()
... except IndexError or KeyError:
... print('Got ya!')
...

>>> with_or_raise(IndexError)
Got ya!

>>> with_or_raise(KeyError)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in with_or_raise
KeyError

所以它没有捕获第二个异常,查看字节码,更清楚为什么:
>>> import dis
>>> dis.dis(with_or_raise)
2 0 SETUP_EXCEPT 10 (to 12)

3 2 LOAD_FAST 0 (exc)
4 CALL_FUNCTION 0
6 RAISE_VARARGS 1
8 POP_BLOCK
10 JUMP_FORWARD 32 (to 44)

4 >> 12 DUP_TOP
14 LOAD_GLOBAL 0 (IndexError)
16 JUMP_IF_TRUE_OR_POP 20
18 LOAD_GLOBAL 1 (KeyError)
>> 20 COMPARE_OP 10 (exception match)
22 POP_JUMP_IF_FALSE 42
24 POP_TOP
26 POP_TOP
28 POP_TOP

5 30 LOAD_GLOBAL 2 (print)
32 LOAD_CONST 1 ('Got ya!')
34 CALL_FUNCTION 1
36 POP_TOP
38 POP_EXCEPT
40 JUMP_FORWARD 2 (to 44)
>> 42 END_FINALLY
>> 44 LOAD_CONST 0 (None)
46 RETURN_VALUE

所以我们可以看到,指令 14 首先加载了 IndexError类到堆栈上。然后检查该值是否为 True ,这是因为 Python 的真实性,最后直接跳转到指令 20,其中 exception match已经完成了。由于指令 18 被跳过, KeyError从未加载到堆栈中,因此不匹配。

我尝试使用 Python 2.7 和 3.6,结果相同。

但是,为什么它是有效的语法?我想它是以下之一:
  • 它是来自真正旧版本的 Python 的产物。
  • 使用 or 实际上有一个有效的用例内except条款。
  • 这只是 Python 解析器的一个限制,它可能必须接受 except 之后的任何表达式。关键词。

  • 我的投票是 3(鉴于我看到了一些关于 Python 新解析器的讨论),但我希望有人能证实这个假设。因为如果它是 2,例如,我想知道那个用例!

    另外,我对如何继续探索有点无能为力。我想我将不得不深入研究 CPython 解析器的源代码,但不知道在哪里可以找到它,也许有更简单的方法?

    最佳答案

    except e , e可以是任何有效的 Python 表达式:

    try1_stmt ::=  "try" ":" suite
    ("except" [expression ["as" identifier]] ":" suite)+
    ...

    [..] For an except clause with an expression, that expression is evaluated, and the clause matches the exception if the resulting object is “compatible” with the exception. An object is compatible with an exception if it is the class or a base class of the exception object or a tuple containing an item compatible with the exception.

    https://docs.python.org/3/reference/compound_stmts.html#the-try-statement



    表达式 IndexError or KeyError产生值 IndexError .所以这相当于:
    except IndexError:
    ...

    关于python - 为什么在 except 子句中使用 `or` 不会导致 SyntaxError?它有有效的用途吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58285119/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com