De scope van een variabele is de context waarin deze beschikbaar is. In Python zijn er 4 hoofdscope-niveaus die je kunt onthouden volgens het principe LEGB:
Het sleutelwoord global stelt je in staat om een variabele die op globaal niveau is gedeclareerd, vanuit een functie te wijzigen.
def foo(): global my_var my_var = 10 # wijzigt de globale variabele
Zonder global wordt de variabele als lokaal beschouwd binnen de functie, zelfs als er een naam is in de externe scope.
"Wat geeft de volgende code weer?"
x = 10 def func(): x = 20 func() print(x)
Antwoord:
Geeft 10 weer, omdat er binnen de functie een nieuwe lokale variabele x wordt aangemaakt, de globale wordt niet gewijzigd.
Verhaal
In de command handler van de bot wilden ze een globale teller opslaan, maar vergaten het woord global:
counter = 0 def increment(): counter += 1 # UnboundLocalError: lokale variabele 'counter' aangeroepen voordat deze is toegewezen
Fout omdat de interpreter denkt dat counter een lokale variabele is (aangezien er in de functie een toewijzing plaatsvindt), en geen globale.
Verhaal
In geneste functies vergaten ze dat zonder het sleutelwoord nonlocal een verborgen variabele een lokale scope creëert:
def outer(): x = 0 def inner(): x += 1 # UnboundLocalError, x wordt als lokaal beschouwd in inner
Correct:
def outer(): x = 0 def inner(): nonlocal x x += 1
Verhaal
Ze schreven een eenregelaar:
x = 5 y = (lambda: (x := x + 1))() # SyntaxError in Python < 3.8, of UnboundLocalError later
Ze vergaten het verschil in scope voor verklaringen en lambda. Niet alle constructies ondersteunen toewijzing binnen lambda, afhankelijk van de versie van Python.