ที่ทำงานฉันพบexcept
ข้อหนึ่งกับor
ผู้ควบคุมเครื่อง:
try:
# Do something.
except IndexError or KeyError:
# ErrorHandling
ฉันรู้ว่าการเรียนการยกเว้นควรจะผ่านการเป็น tuple 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
ดังนั้นมันจึงไม่ได้รับการยกเว้นที่สองและเมื่อมองจาก bytecode มันชัดเจนว่าทำไม:
>>> 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
ซึ่งมันเป็นเพราะงูหลาม truthiness และในที่สุดก็กระโดดโดยตรงกับการเรียนการสอน 20 ที่exception match
จะทำ ตั้งแต่คำสั่ง 18 ถูกข้ามไปKeyError
ไม่เคยถูกโหลดลงบนสแต็กดังนั้นจึงไม่ตรงกัน
ฉันลองด้วย Python 2.7 และ 3.6 ผลลัพธ์เดียวกัน
แต่ทำไมมันถึงเป็นไวยากรณ์ที่ถูกต้อง? ฉันคิดว่ามันเป็นหนึ่งในสิ่งต่อไปนี้:
- มันเป็นสิ่งประดิษฐ์จาก Python เวอร์ชั่นเก่าจริงๆ
- มีกรณีการใช้งานที่ถูกต้องสำหรับการใช้งานจริง
or
ภายในexcept
ข้อ - มันเป็นข้อ จำกัด ของ Parser Python ซึ่งอาจต้องยอมรับการแสดงออกใด ๆ หลังจาก
except
คำหลัก
การลงคะแนนของฉันคือวันที่ 3 (เนื่องจากฉันเห็นการสนทนาเกี่ยวกับ parser ใหม่สำหรับ Python) แต่ฉันหวังว่าจะมีใครบางคนสามารถยืนยันสมมติฐานนั้นได้ เพราะถ้ามันเป็น 2 ฉันต้องการรู้ว่ากรณีการใช้งาน!
นอกจากนี้ฉันยังไม่ค่อยเข้าใจวิธีการสำรวจต่อไป ฉันคิดว่าฉันจะต้องขุดลงในซอร์สโค้ดของโปรแกรมแยกวิเคราะห์ของ CPython แต่ idk จะหาได้ที่ไหนและอาจจะมีวิธีที่ง่ายกว่านี้ไหม