2.11. เงื่อนไข

เงื่อนไข จะรันบล็อกโค้ดเมื่อการทดสอบบางอย่างประเมินว่าเป็นจริง คีย์เวิร์ดคือ if ตามด้วยหนึ่งสาขา elif ("else if") หรือมากกว่าและ else สุดท้ายที่เป็นทางเลือก

n = 42

if n > 0:
    print("positive")
elif n < 0:
    print("negative")
else:
    print("zero")

เนื้อหาของแต่ละสาขาคือทุกอย่างที่เยื้องอยู่ด้านล่าง (สี่ช่องว่างตามแบบแผน) Python จะเดินผ่านสาขาตามลำดับ รันสาขาแรกที่การทดสอบเป็นจริง และข้ามส่วนที่เหลือ บล็อก else รันเมื่อการทดสอบก่อนหน้าทั้งหมดเป็นเท็จ และเป็นทางเลือกเสมอ

A flowchart showing if/elif/else: two diamond decision tests with their bodies, falling through to a final else body when both tests are false.

มีเพียงสาขาเดียวที่จะรันเสมอ การทดสอบจะถูกประเมินจากบนลงล่างจนกว่าจะสำเร็จ ส่วนที่เหลือจะถูกข้าม

2.11.1. ความจริงเชิงบูลีน

การทดสอบใน if ไม่จำเป็นต้องคืนค่า True หรือ False ค่าใดก็ตามนับว่าเป็น truthy หรือ falsy ค่า falsy ได้แก่:

  • False และ None

  • เลขศูนย์: 0, 0.0

  • ลำดับและคอลเลกชันว่าง: "", [], (), {}, b""

ทุกอย่างอื่นเป็น 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 ดังนั้นการตรวจสอบที่มีต้นทุนสูงทางขวาจะรันเมื่อการตรวจสอบที่ถูกกว่าทางซ้ายยังไม่ตัดสินคำถาม