2.11. เงื่อนไข¶
เงื่อนไข จะรันบล็อกโค้ดเมื่อการทดสอบบางอย่างประเมินว่าเป็นจริง คีย์เวิร์ดคือ if ตามด้วยหนึ่งสาขา elif ("else if") หรือมากกว่าและ else สุดท้ายที่เป็นทางเลือก
n = 42
if n > 0:
print("positive")
elif n < 0:
print("negative")
else:
print("zero")
เนื้อหาของแต่ละสาขาคือทุกอย่างที่เยื้องอยู่ด้านล่าง (สี่ช่องว่างตามแบบแผน) Python จะเดินผ่านสาขาตามลำดับ รันสาขาแรกที่การทดสอบเป็นจริง และข้ามส่วนที่เหลือ บล็อก else รันเมื่อการทดสอบก่อนหน้าทั้งหมดเป็นเท็จ และเป็นทางเลือกเสมอ
มีเพียงสาขาเดียวที่จะรันเสมอ การทดสอบจะถูกประเมินจากบนลงล่างจนกว่าจะสำเร็จ ส่วนที่เหลือจะถูกข้าม¶
2.11.1. ความจริงเชิงบูลีน¶
การทดสอบใน if ไม่จำเป็นต้องคืนค่า True หรือ False ค่าใดก็ตามนับว่าเป็น truthy หรือ falsy ค่า falsy ได้แก่:
ทุกอย่างอื่นเป็น truthy ซึ่งช่วยให้เขียนการทดสอบแบบกะทัดรัดได้:
if name: # false on empty string
print("hello", name)
if items: # false on empty list, dict, etc.
process(items)
โปรดทราบว่าความจริงเชิงบูลีนเปลี่ยนความหมาย if value: ไม่เหมือนกับ if value is not None: อย่างแรกยังเป็นเท็จเมื่อ value เป็น 0 หรือ "" เมื่อคุณหมายถึง "สิ่งนี้เป็น None ตรงๆ" ให้ใช้ is None / is not None อย่างชัดเจน
2.11.2. นิพจน์ternary¶
เงื่อนไขสามารถปรากฏภายในนิพจน์:
label = "even" if n % 2 == 0 else "odd"
อ่านว่า "label คือ "even" ถ้า n % 2 == 0 ไม่เช่นนั้น "odd"" เหมาะสำหรับการเขียนบรรทัดเดียว สำหรับอะไรที่ยาวกว่าหนึ่งบรรทัด คำสั่ง if แบบเต็มอ่านง่ายกว่า
2.11.3. การซ้อนกันและการส่งคืนก่อนกำหนด¶
เงื่อนไขสามารถซ้อนกันได้อย่างไม่จำกัด แต่ทุกชั้นการเยื้องเพิ่มเติมทำให้ฟังก์ชันอ่านยากขึ้น ตัวอย่างด้านล่างตรวจสอบเงื่อนไขสี่ข้อก่อนทำงานจริง และทิ้งบรรทัดที่มีประโยชน์ไว้ฝังอยู่ที่สี่ระดับการเยื้อง:
def process(item):
if item is not None:
if item.is_valid():
if item.size() > 0:
if item.owner == "me":
return do_the_work(item)
return None
สองรูปแบบทำให้โค้ดประเภทนี้แบนราบ
2.11.3.1. การส่งคืนก่อนกำหนดสำหรับการป้องกัน¶
จัดการทุกกรณี "ออกจาก" ก่อน แต่ละกรณีมี return ของตัวเอง เพื่อให้ตรรกะหลักอยู่ที่ระดับการเยื้องด้านนอก แต่ละ guard อ่านว่า "กรณีนี้ไม่ใช่สิ่งที่เราจัดการ ออกได้":
def process(item):
if item is None:
return None
if not item.is_valid():
return None
if item.size() == 0:
return None
if item.owner != "me":
return None
return do_the_work(item)
"เส้นทางหลัก" ตอนนี้อยู่บรรทัดเดียวที่ด้านล่างของฟังก์ชัน ไม่ได้ฝังอยู่ในสี่ชั้น สไตล์นี้บางครั้งเรียกว่ารูปแบบ guard clause
2.11.3.2. การรวมการทดสอบด้วย and / or¶
เมื่อเงื่อนไขหลายข้อต้องเป็นจริงทั้งหมดสำหรับสาขาเดียวกัน ให้รวมด้วย and แทนการซ้อนกัน เงื่อนไขที่แต่ละอย่างกระตุ้นสาขาโดยอิสระให้รวมด้วย or:
# all must hold -- use `and`
if user.is_admin() and user.has_permission("write") and not locked:
save()
# any one of them is enough -- use `or`
if c == " " or c == "\t" or c == "\n":
whitespace_count += 1
ทั้งสองรูปแบบจะ short-circuit ดังนั้นการตรวจสอบที่มีต้นทุนสูงทางขวาจะรันเมื่อการตรวจสอบที่ถูกกว่าทางซ้ายยังไม่ตัดสินคำถาม