ProgrammatiePython ontwikkelaar

Wat is de 'LEGB regel' in Python? Hoe werkt het bij het zoeken naar de naam van een variabele? Geef voorbeelden van situaties waarin een verkeerd begrip van deze regel leidt tot niet-triviale bugs.

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

LEGB regel — dit is de regel voor het zoeken naar de naamruimte in Python. De afkorting staat voor:

  • Local — lokale naamruimte (binnen een functie);
  • Enclosing — naamruimten van alle geneste functies;
  • Global — module-ruimte (globale variabelen);
  • Builtin — ingebouwde namen in Python (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.


Strikvraag.

Hoe verandert het gedrag van de functie als u vergeet nonlocal of global te 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.


Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp.


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.