2.11. Uvjeti

Uvjet izvršava blok koda samo kada se neki test izračuna kao istinit. Ključna riječ je if, neobavezno praćena jednom ili više elif („else if”) grana i završnim else.

n = 42

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

Tijelo svake grane jest sve uvučeno ispod nje (po dogovoru četiri razmaka). Python prolazi kroz grane redom, izvršava prvu čiji je test istinit i preskače ostale. Blok else izvršava se samo ako je svaki prethodni test bio lažan; on je uvijek neobavezan.

Dijagram tijeka koji prikazuje if/elif/else: dva romboidna testa odluke s njihovim tijelima, koja prelaze u završno else tijelo kada su oba testa lažna.

Uvijek se izvršava samo jedna grana. Testovi se izračunavaju odozgo prema dolje dok jedan ne uspije; ostali se preskaču.

2.11.1. Istinitost

Test u if ne mora vraćati True ili False – svaka vrijednost računa se kao istinita ili lažna. Lažne vrijednosti su:

  • False i None

  • Broj nula: 0, 0.0

  • Prazni nizovi i zbirke: "", [], (), {}, b""

Sve ostalo je istinito. To vam omogućuje pisanje sažetih testova:

if name:                     # false on empty string
    print("hello", name)

if items:                    # false on empty list, dict, etc.
    process(items)

Imajte na umu da istinitost mijenja značenje. if value: nije isto što i if value is not None: – prvi je također lažan kada je value jednak 0 ili "". Kada stvarno mislite „je li ovo točno None„, izričito koristite is None / is not None.

2.11.2. Ternarni izrazi

Uvjet se može pojaviti unutar izraza:

label = "even" if n % 2 == 0 else "odd"

Čita se kao „label je "even" ako je n % 2 == 0 inače "odd".” Zgodno za jednorednice; za bilo što duže od jednog retka, potpuna naredba if lakša je za čitanje.

2.11.3. Ugnježđivanje i rani povratci

Uvjeti se mogu ugnijezditi proizvoljno duboko, ali svaki dodatni sloj uvlake otežava čitanje funkcije. Primjer ispod provjerava četiri uvjeta prije nego što obavi pravi posao i ostavlja korisni redak zakopan četiri uvlake duboko:

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

Dva obrasca poravnavaju takvu vrstu koda.

2.11.3.1. Rani povratci za zaštite

Obradite svaki slučaj „odustajanja” prvo, svaki sa svojim return, tako da glavna logika ostane na vanjskoj uvlaci. Svaka zaštita čita se kao „ovo nije slučaj koji obrađujemo; izlazimo”:

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)

„Glavni put” sada je jedan redak na dnu funkcije, a ne zakopan unutar četiri sloja. Taj se stil ponekad naziva obrascem zaštitne klauzule.

2.11.3.2. Kombiniranje testova s and / or

Kada nekoliko uvjeta mora vrijediti za istu granu, kombinirajte ih s and umjesto ugnježđivanja. Uvjeti koji svaki samostalno aktiviraju granu kombiniraju se s 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

Oba oblika imaju kratko spajanje, pa se skupa provjera s desne strane izvršava samo kada jeftinije provjere s lijeve strane već nisu riješile pitanje.