Python Academy · Lektion

nonlocal och föränderliga tillstånd

Ändra det omslutande scopet

Lektion 3 av 413 steg

nonlocal och föränderliga tillstånd är en gratis lektion i Python Academy på CoddyKit. Detta är lektion 3 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Python Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Python Academy innehåller totalt 4 lektioner.

Läsa kontra skriva till omslutande variabler

En inre funktion kan fritt läsa en omslutande variabel, men om den försöker tilldela ett värde till det namnet behandlar Python det som en ny lokal variabel i stället. Detta överraskar ofta nybörjare.

def outer():
    count = 0
    def inner():
        return count
    return inner()
print(outer())

Tilldelningsfällan

Om ni tilldelar ett värde till ett omslutande namn utan att deklarera avsikten blir namnet lokalt, så den yttre variabeln uppdateras aldrig. Här går ändringen förlorad.

def outer():
    count = 0
    def bump():
        count = count + 1
    try:
        bump()
    except UnboundLocalError as e:
        print('Error:', e)
outer()

Nyckelordet nonlocal

nonlocal deklarerar att ett namn refererar till en variabel i det närmast omslutande funktionsscopet, så att tilldelningar uppdaterar den yttre variabeln i stället för att skapa en lokal.

def outer():
    count = 0
    def bump():
        nonlocal count
        count += 1
    bump()
    bump()
    return count
print(outer())

En counter-closure

Med nonlocal kan ni bygga en räknare som bevarar sitt tillstånd. Varje anrop ändrar den fångade variabeln och kommer ihåg hur långt den har kommit.

def make_counter():
    count = 0
    def increment():
        nonlocal count
        count += 1
        return count
    return increment
c = make_counter()
print(c())
print(c())
print(c())

Oberoende räknare

Varje räknare behåller sitt eget tillstånd eftersom varje closure fångar en separat variabel.

def make_counter():
    count = 0
    def inc():
        nonlocal count
        count += 1
        return count
    return inc
a = make_counter()
b = make_counter()
print(a(), a(), b())

nonlocal kontra global

nonlocal riktar sig mot ett omslutande funktionsscope, medan global riktar sig mot modulnivån. Använd nonlocal för closures och global för tillstånd som gäller hela modulen.

total = 0
def add_global(n):
    global total
    total += n
add_global(5)
add_global(3)
print(total)

Muterbart tillstånd utan nonlocal

Om det omslutande värdet är ett muterbart objekt, till exempel en lista eller ett dict-objekt, kan ni ändra det på plats utan nonlocal, eftersom ni inte binder om namnet.

def make_logger():
    history = []
    def log(msg):
        history.append(msg)
        return history
    return log
log = make_logger()
log('start')
print(log('stop'))

En ackumulator

Genom att kombinera nonlocal med en closure får ni en löpande ackumulator som lägger varje värde till en ihågkommen totalsumma.

def make_accumulator():
    total = 0
    def add(n):
        nonlocal total
        total += n
        return total
    return add
acc = make_accumulator()
print(acc(10))
print(acc(5))
print(acc(100))

En enkel toggle

nonlocal gör det enkelt att växla ett booleskt tillstånd mellan anrop.

def make_toggle():
    on = False
    def toggle():
        nonlocal on
        on = not on
        return on
    return toggle
t = make_toggle()
print(t(), t(), t())

Återställa tillstånd

Ni kan exponera flera inre funktioner som delar samma omslutande tillstånd, till exempel en som lägger till och en som återställer.

def make_bank():
    balance = 0
    def deposit(n):
        nonlocal balance
        balance += n
        return balance
    def reset():
        nonlocal balance
        balance = 0
        return balance
    return deposit, reset
deposit, reset = make_bank()
print(deposit(50))
print(reset())

nonlocal behöver en befintlig variabel

nonlocal kräver att namnet redan finns i ett omslutande scope; annars genererar Python ett SyntaxError när funktionen definieras. Det kan inte skapa en ny yttre variabel.

def outer():
    value = 'set'
    def inner():
        nonlocal value
        value = 'changed'
    inner()
    return value
print(outer())

Snabbtest

Inuti en nästlad funktion vill ni tilldela ett nytt värde till en variabel från den omslutande funktionen. Vilket nyckelord använder ni?

Sammanfattning: nonlocal och muterbart tillstånd

Sammanfattning:

  • En tilldelning till ett omslutande namn skapar normalt en ny lokal variabel; nonlocal förhindrar det.
  • nonlocal riktar sig mot det omslutande funktionsscopet, medan global riktar sig mot modulen.
  • Det behövs ingen deklaration för att ändra ett muterbart objekt på plats.
  • Closures med nonlocal kan bygga räknare, ackumulatorer och togglar som kommer ihåg tillstånd.
def make_counter():
    n = 0
    def inc():
        nonlocal n
        n += 1
        return n
    return inc
c = make_counter()
print(c(), c())
Gratis att börja

Lär dig Python med en AI-lärare – gratis

Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.

Kurser
76
Lektioner
320

Vanliga frågor

Är lektionen ”nonlocal och föränderliga tillstånd” gratis?

Ja – hela texten till ”nonlocal och föränderliga tillstånd” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Python Academy, kan Ni uppgradera till CoddyKit PRO. Kursen i Python Academy innehåller totalt 4 lektioner.

Vad lär jag mig i ”nonlocal och föränderliga tillstånd”?

Ändra det omslutande scopet Ni övar på Python Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.

Behöver jag någon erfarenhet för att börja lära mig Python Academy?

Du behöver inga förkunskaper. Utbildningen i Python Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 3 av 4.

Hur lång tid tar lektionen ”nonlocal och föränderliga tillstånd”?

De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.

Kan jag skriva och köra kod i den här Python Academy-lektionen?

Ja. Varje Python Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.

Alla lektioner i den här kursen

  1. Förstaklassfunktioner
  2. Slutningar och fria variabler
  3. nonlocal och föränderliga tillstånd
  4. Partiella funktioner
← Tillbaka till Python Academy