← Terug naar overzicht
Basisconcepten · Python

Functions & scope

Functions definiëren, parameters, en local/global scope

5.1 Functions definiëren

def groet(naam):
    return "Hallo, " + naam + "!"

print(groet("Ernest"))   # Hallo, Ernest!

Onderdelen:

5.2 Parameters: default values en keyword arguments

def bereken_prijs(prijs, korting=0):
    return prijs - (prijs * korting)

print(bereken_prijs(100))          # 100 (geen korting)
print(bereken_prijs(100, 0.1))     # 90.0
print(bereken_prijs(prijs=100, korting=0.2))  # 80.0

*args en **kwargs (variabel aantal arguments):

def tel_op(*getallen):
    return sum(getallen)

print(tel_op(1, 2, 3, 4))   # 10

def toon_info(**gegevens):
    for sleutel, waarde in gegevens.items():
        print(sleutel, ":", waarde)

toon_info(naam="Tom", huisdieren=1)

5.3 Scope: waar bestaat een variabele?

Local scope: variabelen die binnen een function worden aangemaakt, bestaan alleen daarbinnen.

def mijn_functie():
    x = 10   # local variabele
    print(x)

mijn_functie()
print(x)   # FOUT! NameError: x bestaat hier niet

Global scope: variabelen buiten elke function zijn overal leesbaar (maar niet zomaar aanpasbaar).

teller = 0

def verhoog():
    print(teller)   # dit werkt: lezen mag

verhoog()
teller = 0

def verhoog():
    teller += 1   # FOUT! UnboundLocalError

verhoog()

Om een global variabele binnen een function te wijzigen, is het global keyword nodig:

teller = 0

def verhoog():
    global teller
    teller += 1

verhoog()
print(teller)   # 1

Vuistregel: gebruik global zo min mogelijk, het maakt code moeilijker te volgen. Geef liever waarden mee als parameter en return het resultaat.

def verhoog(teller):
    return teller + 1

teller = 0
teller = verhoog(teller)
print(teller)   # 1

5.4 Scope en modulariteit: een function als "los bestand"

Een handige manier om scope te begrijpen: vergelijk een function met een apart Python-bestand.

Stel je hebt twee losse .py-bestanden. Een variabele die je in bestand_a.py aanmaakt, bestaat automatisch niet in bestand_b.py, die twee bestanden weten niets van elkaars variabelen, tenzij je ze expliciet doorgeeft (bijvoorbeeld via een import). Een function werkt in principe hetzelfde:

def bereken_oppervlakte(lengte, breedte):
    oppervlakte = lengte * breedte   # bestaat alleen "binnen dit bestandje"
    return oppervlakte

resultaat = bereken_oppervlakte(4, 5)
print(resultaat)      # 20
print(oppervlakte)    # FOUT! oppervlakte bestaat hier niet, net als in een ander bestand

Dit idee heet modulariteit: een function is een afgesloten eenheid. Als gebruiker van de function hoef je niet te weten wat er precies binnenin gebeurt, je hoeft alleen te weten wat erin moet (de parameters) en wat eruit komt (de return value). Dat maakt code makkelijker te lezen, te testen en te hergebruiken: de inhoud van een function kan later aangepast worden zonder de rest van het programma kapot te maken, zolang de "ingang" en "uitgang" hetzelfde blijven.

5.5 Scope-volgorde: de LEGB rule

Python zoekt variabelen in deze volgorde op:

  1. Local: binnen de huidige function
  2. Enclosing: binnen een omliggende function (bij geneste functions)
  3. Global: op module-niveau
  4. Built-in: Python's ingebouwde namen (zoals print, len)
x = "globaal"

def buiten():
    x = "omliggend"
    def binnen():
        x = "lokaal"
        print(x)   # lokaal
    binnen()
    print(x)   # omliggend

buiten()
print(x)   # globaal