2.11. Ehtolauseet¶
Ehtolause suorittaa koodilohkon vain silloin, kun jokin testi arvioituu todeksi. Avainsana on if, jota voi valinnaisesti seurata yksi tai useampi elif (”else if”) -haara ja lopullinen else.
n = 42
if n > 0:
print("positive")
elif n < 0:
print("negative")
else:
print("zero")
Kunkin haaran runko on kaikki sen alle sisennetty (sopimuksen mukaan neljä välilyöntiä). Python käy haarat läpi järjestyksessä, suorittaa ensimmäisen, jonka testi on tosi, ja ohittaa loput. else-lohko suoritetaan vain, jos jokainen edeltävä testi oli epätosi; se on aina valinnainen.
Vain yksi haara suoritetaan koskaan. Testit arvioidaan ylhäältä alas, kunnes yksi onnistuu; loput ohitetaan.¶
2.11.1. Totuusarvoisuus¶
if-lauseen testin ei tarvitse palauttaa True tai False – mikä tahansa arvo lasketaan joko todenkaltaiseksi tai epätodenkaltaiseksi. Epätodenkaltaiset arvot ovat:
Kaikki muu on todenkaltaista. Tämä antaa sinun kirjoittaa tiiviitä testejä:
if name: # false on empty string
print("hello", name)
if items: # false on empty list, dict, etc.
process(items)
Huomaa, että totuusarvoisuus muuttaa merkityksen. if value: ei ole sama kuin if value is not None: – ensimmäinen on epätosi myös silloin, kun value on 0 tai "". Kun todella tarkoitat ”onko tämä täsmälleen None”, käytä eksplisiittisesti is None / is not None.
2.11.2. Ehtolausekkeet (ternary)¶
Ehtolause voi esiintyä lausekkeen sisällä:
label = "even" if n % 2 == 0 else "odd"
Luetaan ”label on "even" jos n % 2 == 0 muuten "odd".” Kätevä yksirivisille; mihin tahansa yhtä riviä pidempään täysi if-lause on helpompi lukea.
2.11.3. Sisäkkäisyys ja varhaiset paluut¶
Ehtolauseet voivat olla sisäkkäin mielivaltaisen syvälle, mutta jokainen ylimääräinen sisennystaso tekee funktiosta vaikeammin luettavan. Alla oleva esimerkki tarkistaa neljä ehtoa ennen varsinaista työtä ja jättää hyödyllisen rivin hautautuneeksi neljän sisennyksen taakse:
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
Kaksi kuviota litistää tämänkaltaista koodia.
2.11.3.1. Varhaiset paluut vartijoina¶
Käsittele jokainen ”keskeytä”-tapaus ensin, kukin omalla return-lauseellaan, jotta päälogiikka pysyy uloimmalla sisennyksellä. Kukin vartija luetaan ”tämä ei ole tapaus, jonka käsittelemme; poistu”:
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)
”Pääpolku” on nyt yksi rivi funktion alaosassa, ei hautautuneena neljän kerroksen sisään. Tätä tyyliä kutsutaan joskus vartijaehdon (guard clause) kuvioksi.
2.11.3.2. Testien yhdistäminen and / or -operaattoreilla¶
Kun useiden ehtojen on kaikkien pädettävä samaan haaraan, yhdistä ne and-operaattorilla sisäkkäisyyden sijaan. Ehdot, jotka kukin itsenäisesti laukaisevat haaran, yhdistetään or-operaattorilla:
# 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
Molemmat muodot oikosulkevat, joten kallis tarkistus oikealla puolella suoritetaan vain, kun vasemmalla olevat halvemmat tarkistukset eivät ole jo ratkaisseet kysymystä.