LEGB regel — dit is de regel voor het zoeken naar de naamruimte in Python. De afkorting staat voor:
len, list, enzovoort).Wanneer Python een variabele tegenkomt, zoekt het eerst lokaal, dan in geneste functies, vervolgens in de globale module-ruimte, en ten slotte in de naamruimte van ingebouwde objecten:
def outer(): x = 'enclosing' def inner(): x = 'local' print(x) inner() outer() # 'local'
Als we de toewijzing van x binnen inner() weglaten, zal Python x nemen uit de enclosing scope (outer). Als daar ook geen variabele is, wordt er globaal gezocht, en daarna in de ingebouwde naamruimten.
Hoe verandert het gedrag van de functie als u vergeet
nonlocalofglobalte declareren bij het wijzigen van een variabele op hoger niveau?
Antwoord:
Als je probeert de variabele van een hogere scope binnen een geneste functie te wijzigen zonder nonlocal (of global — als de variabele in de module is) te declareren, maakt Python een nieuwe lokale variabele aan zonder de externe te wijzigen.
Voorbeeld:
x = 10 def foo(): x = 20 # Dit is een nieuwe lokale x, de globale verandert niet foo() print(x) # 10
Om de globale x te veranderen:
def foo(): global x x = 20
Gebruik nonlocal voor variabelen in de externe functie.
Verhaal 1
In een educatief project werden geneste functies gebruikt om het aantal aanroepen te tellen. De ontwikkelaar schreef:
def counter(): count = 0 def inc(): count += 1 return count return inc
Maar er ontstond een UnboundLocalError, omdat count binnen inc() als een nieuwe (lokale) count werd beschouwd. Oplossing: declareer count als nonlocal.
Verhaal 2
In een webapplicatie wilden ze in de handler de globaal gedefinieerde cache aanpassen:
cache = {} def add_to_cache(key, value): cache[key] = value
Maar als ze binnen de functie probeerden de cache volledig opnieuw te schrijven, bijvoorbeeld cache = {key: value}, zou dit een nieuwe lokale cache creëren, die niet was gekoppeld aan de globale, vanwege het gebrek aan global cache.
Verhaal 3
In een groot ETL-systeem werd een bug aangetroffen: programmeurs lieten de variabele result zonder expliciete initialisatie binnen de functie, in de veronderstelling dat deze uit de externe scope genomen zou worden. Maar na enkele iteraties begon het resultaat te falen, omdat er een schrijven was result += value, en niet result = result + value (zonder nonlocal/global) — en result werd opnieuw geïnitialiseerd bij elke aanroep.