persone hanno risposto alla tua domanda, ma nessuno sembra affrontare perché proprio questo sta accadendo.
Il seguente codice solleva un UnboundLocalError
Allora, perché ?Diamo una citazione dal FAQ:
Quando si effettua un'assegnazione ad una variabile in un campo di applicazione, che variabile diventa locale per tale ambito e ombre qualsiasi variabile nome simile nel perimetro esterno.
All'interno della funzione annidata si sta eseguendo un incarico con l'operatore +=
. Ciò significa cheeseguirà approssimativamente i = i + 1
(da una prospettiva vincolante). Di conseguenza, nell'espressione i + 1
verrà ricercata nell'ambito locale (poiché viene utilizzata nell'istruzione di assegnazione) per la funzione dove non verrà trovata, con conseguente UnboundLocalError: reference before assignment
.
Ci sono molti modi per affrontare questo e Python 3 è più elegante nell'approccio si può prendere di Python 2.
Python 3 nonlocal
:
I nonlocal
dichiarazioni dice a Python per cercare un nome in l'ambito racchiude (quindi in questo caso, nell'ambito della funzione foo()
) per nome riferimenti:
def foo():
i = 0
def incr():
nonlocal i
i +=1
incr()
print(i)
Function attributes Python 2.x
and 3.x
:
Ricordare che le funzioni sono oggetti di prima classe, in quanto tali possono memorizzare lo stato. Usa gli attributi della funzione per accedere e modificare lo stato della funzione, la cosa buona con questo approccio è che funziona su tutti i pitoni e non richiede le dichiarazioni global, nonlocal
.
def foo():
foo.i = 0
def incr():
foo.i +=1
incr()
print(foo.i)
The global
Statement (Python 2.x
, 3.x
):
davvero il più brutto del gruppo, ma ottiene il lavoro fatto:
i = 0
def foo():
def incr():
global i
i += 1
incr()
print(i)
foo()
La possibilità di passare un argomento alla funzione ottiene lo stesso risultato ma non si riferisce alla mutazione del campo di applicazione nel senso nonlocal
e global
sono ed è più simile agli attributi di funzione presentati. Sta creando una nuova variabile locale nella funzione inc
e quindi re-binding il nome in i
con lo i = incr(i)
ma, in effetti, ha completato il lavoro.
È possibile passare 'i' come argomento. – Maroun
È possibile aggiornare il valore di 'i' come' i = incr() ' –
@MarounMaroun Judgind da questa domanda, cosa Python, non ha chiusure? 0_o 'Non mi è familiare, però. O è perché 'def' definisce una funzione nel namespace globale? Sono solo curioso e non voglio imparare Python solo per questo. :) – hijarian