2.11. Conditionals¶
En villkorssats kör ett kodblock endast när något test utvärderas till sant. Nyckelordet är if, valfritt följt av en eller flera elif-grenar (”else if”) och en avslutande else.
n = 42
if n > 0:
print("positive")
elif n < 0:
print("negative")
else:
print("zero")
Kroppen i varje gren är allt som är indenterat under den (fyra blanksteg enligt konvention). Python går igenom grenarna i ordning, kör den första vars test är sant och hoppar över resten. else-blocket körs endast om varje föregående test var falskt; det är alltid valfritt.
Endast en gren körs någonsin. Tester utvärderas uppifrån och ned tills ett lyckas; resten hoppas över.¶
2.11.1. Sanningsvärde¶
Ett test i ett if behöver inte returnera True eller False – vilket värde som helst räknas som antingen sant (truthy) eller falskt (falsy). De falska värdena är:
Allt annat är sant. Detta låter dig skriva kompakta tester:
if name: # false on empty string
print("hello", name)
if items: # false on empty list, dict, etc.
process(items)
Var medveten om att sanningsvärdet ändrar betydelsen. if value: är inte samma sak som if value is not None: – den första är också falsk när value är 0 eller "". När du verkligen menar ”är detta exakt None”, använd is None / is not None uttryckligen.
2.11.2. Ternära uttryck¶
En villkorssats kan förekomma inuti ett uttryck:
label = "even" if n % 2 == 0 else "odd"
Läs som ”label är "even" om n % 2 == 0 annars "odd".” Praktiskt för enradare; för något mer än en rad är en fullständig if-sats lättare att läsa.
2.11.3. Nästling och tidiga returer¶
Villkorssatser kan nästlas godtyckligt djupt, men varje extra lager av indentering gör en funktion svårare att läsa. Exemplet nedan kontrollerar fyra villkor innan det utför det verkliga arbetet och lämnar den användbara raden begravd fyra indenteringar in:
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
Två mönster plattar ut den här sortens kod.
2.11.3.1. Tidiga returer för skyddsvillkor¶
Hantera varje ”avbryt”-fall först, var och en med sitt eget return, så att huvudlogiken stannar kvar på den yttre indenteringen. Varje skyddsvillkor läses som ”detta är inte ett fall vi hanterar; lämna”:
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)
”Huvudvägen” är nu en rad längst ned i funktionen, inte begravd inuti fyra lager. Den här stilen kallas ibland för guard clause-mönstret.
2.11.3.2. Kombinera tester med and / or¶
När flera villkor alla måste gälla för samma gren, kombinera dem med and i stället för att nästla. Villkor som var och en oberoende utlöser grenen kombineras med 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
Båda formerna kortsluter, så en dyr kontroll på höger sida körs endast när de billigare kontrollerna till vänster inte redan har avgjort frågan.