2014-05-04 13 views
5

Dal Python FAQ, possiamo leggere:Python: Perché si dice che le variabili a cui si fa riferimento sono solo implicitamente globali?

In Python, le variabili cui si fa riferimento solo all'interno di una funzione sono implicitamente globale

E dal Python Tutorial on defining functions, possiamo leggere:

L'esecuzione di una funzione introduce una nuova tabella dei simboli utilizzata per le variabili locali della funzione. Più precisamente, tutte le assegnazioni di variabili in una funzione memorizzano il valore nella tabella dei simboli locale; mentre i riferimenti variabili prima guardano nella tabella dei simboli locale, quindi nelle tabelle dei simboli locali delle funzioni di chiusura, quindi nella tabella dei simboli globali e infine nella tabella dei nomi incorporati

Ora ho perfettamente capito il tutorial dichiarazioni, ma poi dicendo che variables that are only referenced inside a function are implicitly global mi sembra abbastanza vago.

Perché dire che sono implicitamente globali se effettivamente iniziamo a guardare le tabelle dei simboli locali e quindi seguiamo quelle più "generali"? È solo un modo per dire che se si fa riferimento solo a una variabile all'interno di una funzione, non è necessario preoccuparsi se è locale o global?

risposta

7

Esempi

(vedere più avanti per una sintesi)

Ciò significa che se una variabile è mai assegnato a nel corpo di una funzione, allora sarà trattato come globale.

Questo spiega perché le seguenti opere (a viene trattato come globale):

a = 1 

def fn(): 
    print a # This is "referencing a variable" == "reading its value" 

# Prints: 1 

Tuttavia, se la variabile viene assegnato da qualche parte nel corpo della funzione, allora saranno trattati come locale per l'intero corpo della funzione.

Ciò include le affermazioni trovate prima di a cui è assegnato (vedere l'esempio di seguito).

Questo spiega perché il seguente lavoro è non. Qui, a è trattata come locali,

a = 1 

def fn(): 
    print a 
    a = 2 # <<< We're adding this 

fn() 

# Throws: UnboundLocalError: local variable 'a' referenced before assignment 

Si può avere Python trattare una variabile come globale con la dichiarazione global a. In tal caso, la variabile verrà considerata globale, , per l'intero corpo della funzione.

a = 1 

def fn(): 
    global a # <<< We're adding this 
    print a 
    a = 2 

fn() 
print a 

# Prints: 1 
# Then, prints: 2 (a changed in the global scope too) 

Sommario

A differenza di quanto ci si potrebbe aspettare, Python non caduta di nuovo alla portata globale, se non riesce a trovare a in ambito locale.

Ciò significa che una variabile è locale o globale per l'intero corpo funzione: non può essere globale e quindi diventare locale.

Ora, per quanto riguarda se una variabile viene considerata locale o globale, Python segue la seguente regola. Le variabili sono:

  • globale se solo si fa riferimento e mai assegnato a
  • globale se l'istruzione global viene utilizzato
  • locale se la variabile è assegnato ad almeno una volta (e global non è stato utilizzato)

Note aggiuntive

infatti, "implic itly global "non significa realmente globale. Ecco un modo migliore per pensarci:

  • "locale", "da qualche parte all'interno della funzione"
  • "globale" in realtà significa "da qualche parte al di fuori della funzione"

Quindi, se una variabile viene "implicitamente globale" (== "al di fuori della funzione"), allora la sua "ambito di inclusione" sarà cercato prima:

a = 25 

def enclosing(): 
    a = 2 
    def enclosed(): 
     print a 
    enclosed() 

enclosing() 

# Prints 2, as supplied in the enclosing scope, instead of 25 (found in the global scope) 

Ora, come al solito, global consente di fare riferimento alla sc globale OPE.

a = 25 

def enclosing(): 
    a = 2 
    def enclosed(): 
     global a # <<< We're adding this 
     print a 
    enclosed() 

enclosing() 

# Prints 25, as supplied in the global scope 

Ora, se avete bisogno di assegnare al a in enclosed, e voleva a 'il valore s di essere cambiato in enclosing' ambito s, ma non in ambito globale, allora si avrebbe bisogno nonlocal, che è nuovo in Python 3. In Python 2, non è possibile.

1

Lo schema di risoluzione dei nomi di Python viene talvolta chiamato la regola LEGB, dopo i nomi dell'ambito .

Quando si utilizza un nome non qualificato all'interno di una funzione, Python cerca fino a quattro scopi-locale (L) portata, poi gli ambiti locali di qualsiasi allegando (E) defs e lambda, poi la globale (G), e quindi lo spazio integrato (B) e si ferma a il primo luogo in cui viene trovato il nome. Se il nome non viene trovato durante questa ricerca, Python segnala un errore.

  • Le assegnazioni di nomi creano o modificano i nomi locali per impostazione predefinita.
  • I riferimenti di nomi cercano al massimo quattro ambiti: locale, quindi includendo le funzioni (se presenti), quindi globali, quindi integrate.
  • I nomi dichiarati nelle istruzioni globali e non locali mappano i nomi assegnati per includere rispettivamente gli ambiti del modulo e delle funzioni.

In altre parole, tutti i nomi assegnati all'interno di una funzione def dichiarazione (o un lambda) sono i locali per impostazione predefinita. Le funzioni possono liberamente utilizzare nomi assegnati a in modo sintattico per includere le funzioni e l'ambito globale, ma devono dichiarare tali nonlocals e globals per cambiarli.

Riferimento: http://goo.gl/woLW0F

+2

Attribuzione mancante: [Learning Python: potente programmazione orientata agli oggetti] (http://goo.gl/woLW0F) –

+0

@A श wini च haudhary Fine :) – ajkumar25

1

Questo è confusa e la documentazione poteva sopportare di essere più chiaro.

"referenziato" in questo contesto indica che un nome non viene assegnato ma semplicemente letto da. Ad esempio, mentre il a = 1 è assegnato a a, print(a) (sintassi Python 3) fa riferimento a a senza alcun incarico.

Se riferimentoa come sopra senza alcun incarico, poi l'interprete Python cerca lo spazio dei nomi genitore dello spazio dei nomi corrente, in modo ricorsivo fino a raggiungere il namespace globale.

D'altra parte, se si imposta su una variabile, tale variabile viene definita solo all'interno dello spazio dei nomi locale se non diversamente dichiarato con la parola chiave global. Quindi, a = 1 crea un nuovo nome, a, all'interno dello spazio dei nomi locale. Questo ha la precedenza su qualsiasi altra variabile denominata a in spazi dei nomi superiori.

1

A differenza di altri linguaggi, Python non cerca il nome di una variabile in una tabella di simboli locale e quindi ricade indietro per cercarlo in un ambito più grande se non viene trovato lì. Le variabili sono determinate per essere locali al momento della compilazione, non in fase di esecuzione, per essere assegnate a (incluso essere passati come parametro). Qualsiasi nome non assegnato (e non dichiarato esplicitamente globale) è considerato globale e verrà cercato solo nello spazio dei nomi globale. Ciò consente a Python di ottimizzare l'accesso alle variabili locali (usando il codice byte LOAD_FAST), motivo per cui i locali sono più veloci.

Ci sono alcune grinze che riguardano le chiusure (e in Python 3, nonlocal) ma questo è il caso generale.

Problemi correlati