Trong công việc, tôi tình cờ thấy một except
điều khoản với một or
nhà điều hành:
try:
# Do something.
except IndexError or KeyError:
# ErrorHandling
Tôi biết các lớp ngoại lệ nên được thông qua như một tuple, nhưng nó đã nói với tôi rằng nó thậm chí sẽ không gây ra a SyntaxError
.
Vì vậy, trước tiên tôi muốn điều tra xem nó thực sự hoạt động. Và nó không.
>>> 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
Vì vậy, nó đã không bắt được ngoại lệ thứ hai và nhìn vào mã byte, nó trở nên rõ ràng hơn tại sao:
>>> 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
Vì vậy, chúng ta có thể thấy, hướng dẫn 14 đầu tiên tải IndexError
lớp lên ngăn xếp. Sau đó, nó kiểm tra xem giá trị đó có phải không True
, đó là do tính trung thực của Python và cuối cùng nhảy trực tiếp đến hướng dẫn 20 nơi exception match
thực hiện. Vì hướng dẫn 18 đã bị bỏ qua, KeyError
không bao giờ được tải lên ngăn xếp và do đó không khớp.
Tôi đã thử với Python 2.7 và 3.6, kết quả tương tự.
Nhưng sau đó, tại sao nó là cú pháp hợp lệ? Tôi tưởng tượng nó là một trong những điều sau đây:
- Đây là một tạo tác từ một phiên bản Python thực sự cũ.
- Thực sự có một trường hợp sử dụng hợp lệ để sử dụng
or
trong mộtexcept
mệnh đề. - Nó chỉ đơn giản là một giới hạn của trình phân tích cú pháp Python có thể phải chấp nhận bất kỳ biểu thức nào sau
except
từ khóa.
Phiếu bầu của tôi là 3 (được cho là tôi đã thấy một số cuộc thảo luận về trình phân tích cú pháp mới cho Python) nhưng tôi hy vọng ai đó có thể xác nhận giả thuyết đó. Bởi vì nếu là 2 chẳng hạn, tôi muốn biết trường hợp sử dụng đó!
Ngoài ra, tôi có một chút không biết về cách tôi tiếp tục cuộc thám hiểm đó. Tôi tưởng tượng rằng tôi sẽ phải đào sâu vào mã nguồn của trình phân tích cú pháp CPython nhưng idk tìm ở đâu và có thể có một cách dễ dàng hơn?