ในหลาย ๆ กรณี Python มีลักษณะและพฤติกรรมเหมือนภาษาอังกฤษตามธรรมชาติ แต่นี่เป็นกรณีหนึ่งที่นามธรรมล้มเหลว ผู้คนสามารถใช้เบาะแสบริบทเพื่อระบุว่า "Jon" และ "Inbar" เป็นอ็อบเจ็กต์ที่เชื่อมต่อกับคำกริยา "equals" แต่ตัวแปล Python มีความเข้าใจตามตัวอักษรมากกว่า
if name == "Kevin" or "Jon" or "Inbar":
มีเหตุผลเทียบเท่ากับ:
if (name == "Kevin") or ("Jon") or ("Inbar"):
ซึ่งสำหรับผู้ใช้ Bob เทียบเท่ากับ:
if (False) or ("Jon") or ("Inbar"):
ตัวor
ดำเนินการเลือกอาร์กิวเมนต์แรกที่มีค่าความจริงเป็นบวก:
if ("Jon"):
และเนื่องจาก "จอน" มีค่าความจริงเป็นบวกif
บล็อกจึงดำเนินการ นั่นคือสาเหตุที่ทำให้ "Access ได้รับ" ถูกพิมพ์โดยไม่คำนึงถึงชื่อที่กำหนด
การให้เหตุผลทั้งหมดนี้ใช้กับสำนวนif "Kevin" or "Jon" or "Inbar" == name
นี้ด้วย ค่าแรก"Kevin"
เป็นจริงดังนั้นif
บล็อกจึงดำเนินการ
มีสองวิธีทั่วไปในการสร้างเงื่อนไขนี้อย่างเหมาะสม
ใช้ตัว==
ดำเนินการหลายตัวเพื่อตรวจสอบแต่ละค่าอย่างชัดเจน:
if name == "Kevin" or name == "Jon" or name == "Inbar":
สร้างลำดับของค่าที่ถูกต้องและใช้ตัวin
ดำเนินการเพื่อทดสอบการเป็นสมาชิก:
if name in {"Kevin", "Jon", "Inbar"}:
โดยทั่วไปแล้วสองวินาทีควรเป็นที่ต้องการเพราะอ่านง่ายกว่าและเร็วกว่าด้วย:
>>> import timeit
>>> timeit.timeit('name == "Kevin" or name == "Jon" or name == "Inbar"', setup="name='Inbar'")
0.4247764749999945
>>> timeit.timeit('name in {"Kevin", "Jon", "Inbar"}', setup="name='Inbar'")
0.18493307199999265
สำหรับผู้ที่ต้องการหลักฐานที่if a == b or c or d or e: ...
แยกวิเคราะห์เช่นนี้ ast
โมดูลในตัวให้คำตอบ:
>>> import ast
>>> ast.parse("if a == b or c or d or e: ...")
<_ast.Module object at 0x1031ae6a0>
>>> ast.dump(_)
"Module(body=[If(test=BoolOp(op=Or(), values=[Compare(left=Name(id='a', ctx=Load()), ops=[Eq()], comparators=[Name(id='b', ctx=Load())]), Name(id='c', ctx=Load()), Name(id='d', ctx=Load()), Name(id='e', ctx=Load())]), body=[Expr(value=Ellipsis())], orelse=[])])"
>>>
ดังนั้นtest
ของif
ลักษณะคำสั่งเช่นนี้
BoolOp(
op=Or(),
values=[
Compare(
left=Name(id='a', ctx=Load()),
ops=[Eq()],
comparators=[Name(id='b', ctx=Load())]
),
Name(id='c', ctx=Load()),
Name(id='d', ctx=Load()),
Name(id='e', ctx=Load())
]
)
ในฐานะที่เป็นหนึ่งสามารถดูจะเป็นผู้ประกอบการบูลีนor
นำไปใช้กับหลายvalues
คือa == b
และc
, และd
e