2010-05-13 15 views
156

Sono nuovo di Python, quindi questa è probabilmente una semplice domanda di scoping. Il seguente codice in un file Python (modulo) mi confonde un po ':Qual è lo scopo di una variabile inizializzata in un'istruzione if?

if __name__ == '__main__': 
    x = 1 

print x 

In altre lingue con cui ho lavorato in, questo codice sarebbe un'eccezione, come variabile x è locale alla dichiarazione if e dovrebbe non esiste al di fuori di esso. Ma questo codice viene eseguito e stampato 1. Qualcuno può spiegare questo comportamento? Tutte le variabili create in un modulo sono globali/disponibili per l'intero modulo?

+7

Un altro capriccio di cui potresti non essere a conoscenza: se l'istruzione 'if' di cui sopra non è vera (cioè,' __name__' è * not * ''__main __'', ad esempio quando importi il ​​modulo invece di eseguirlo di primo livello), quindi 'x' non sarà mai stato associato, e la successiva istruzione' print x' genererà un 'NameError: name 'x' non è definito'. – Santa

risposta

155

Le variabili Python hanno lo scopo della funzione, della classe o del modulo più interno a cui sono assegnate. I blocchi di controllo come i blocchi if e while non contano, quindi una variabile assegnata all'interno di uno if è ancora associata a una funzione, classe o modulo.

(Funzioni implicite definiti da un generatore di espressione o di un elenco/set/dict comprensione contano, così come le espressioni lambda. Non si può farcire un'istruzione di assegnazione in una di queste, ma i parametri lambda e for obiettivi clausola sono assegnazione implicita.)

36

Sì, sono nella stessa "ambito locale", e in realtà il codice come questo è comune in Python:

if condition: 
    x = 'something' 
else: 
    x = 'something else' 

use(x) 

Nota che x non è dichiarato o inizializzato prima che la condizione, come sarebbe essere in C o Java, per esempio.

In altre parole, Python non ha ambiti a livello di blocco. Attenzione, però, con esempi come

if False: 
    x = 3 
print(x) 

che chiaramente sollevare un'eccezione NameError.

1

Sì. È anche vero per lo scope for. Ma non funzioni, ovviamente.

Nel tuo esempio: se la condizione nell'istruzione if è false, non sarà tuttavia definito x.

1

si sta eseguendo questo codice dalla riga di comando, pertanto le condizioni if sono vere e viene impostato x. Confronto:

>>> if False: 
    y = 42 


>>> y 
Traceback (most recent call last): 
    File "<pyshell#6>", line 1, in <module> 
    y 
NameError: name 'y' is not defined 
28

Scope in pitone segue questo ordine:

  • Cerca in ambito locale

  • Cerca la portata di qualsiasi funzione di cinta

  • Cerca la portata globale

  • Cerca i built-in

(source)

noti che if e altro loop/costrutti ramificati non sono elencati - solo le classi, funzioni e moduli fornire portata in Python, quindi tutto dichiarata in un blocco if ha la stessa portata come qualcosa che è scomparso fuori dal blocco. Le variabili non vengono controllate in fase di compilazione, motivo per cui altre lingue generano un'eccezione. In python, fintanto che la variabile esiste nel momento in cui viene richiesta, non verrà generata alcuna eccezione.

5

Come ha detto Eli, Python non richiede la dichiarazione delle variabili.In C si direbbe:

int x; 
if(something) 
    x = 1; 
else 
    x = 2; 

ma in Python dichiarazione è implicita, in modo che quando si assegna ad x si dichiara automaticamente. È perché Python è tipizzato dinamicamente - non funzionerebbe in un linguaggio tipizzato staticamente, perché a seconda del percorso utilizzato, una variabile potrebbe essere utilizzata senza essere dichiarata. Questo potrebbe essere catturato in fase di compilazione in un linguaggio tipizzato in modo statico, ma con un linguaggio digitato in modo dinamico è consentito.

L'unico motivo per cui una lingua tipizzata in modo statico è limitata alla necessità di dichiarare variabili al di fuori delle istruzioni if a causa di questo problema. Abbraccia la dinamica!

7

A differenza di linguaggi come C, una variabile Python è in ambito per l'intera funzione (o classe o modulo) dove appare, non solo nel "blocco" più interno. È come se avessi dichiarato int x nella parte superiore della funzione (o classe, o modulo), tranne che in Python non devi dichiarare le variabili.

Si noti che l'esistenza della variabile x viene verificata solo in fase di esecuzione, ovvero quando si arriva all'istruzione print x. Se __name__ non corrisponde a "__main__", si otterrebbe un'eccezione: NameError: name 'x' is not defined.

+0

Le classi non creano un ambito; una variabile "locale" in una classe viene semplicemente aggiunta al dettato della classe alla creazione. – chepner