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.

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.

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.