2010-03-01 22 views
7

Attualmente sto sviluppando alcune cose in Python e ho una domanda sull'ambito delle variabili.Correttezza dello scope variabile

Questo è il codice:

a = None 
anything = False 
if anything: 
    a = 1 
else: 
    a = 2 

print a # prints 2 

Se rimuovo la prima linea (a = None) il codice funziona ancora come prima. Comunque, in questo caso, dichiarerei la variabile all'interno di un blocco "se", e rispetto ad altri linguaggi come Java, quella variabile sarebbe visibile solo all'interno del "se".

Come funziona esattamente lo scope variabile in Python e quale è il modo migliore di programmare in casi come questo?

Grazie!

+2

Non esiste una cosa come "dichiarare" una variabile in python! –

risposta

8

Come regola generale, gli ambiti sono creati in tre punti:

  1. File-scope - altrimenti noto come ambito modulo
  2. Class-scope - creata all'interno class blocchi
  3. Funzione-scope - creata all'interno def blocchi

(ci sono alcune eccezioni a queste.)

L'assegnazione a un nome la riserva nello spazio dei nomi dell'ambito, contrassegnata come non legata fino al raggiungimento del primo compito.Quindi, per un modello mentale, stai assegnando valori ai nomi in un ambito.

+1

In realtà ci sono quattro posti, il quarto è l'ambito globale. Ma questo dipende davvero dal fatto che consideri globale un ambito in sé. – jathanism

+1

Per quanto comprendo l'ambito globale, è generalmente sinonimo di ambito file/modulo. Le eccezioni che conosco riguardano il passaggio di un dizionario per le globali in 'exec' o' eval'. Dalla memoria, il quarto ambito si trova nelle espressioni del generatore, non permettendo alle variabili iteratore di uscire. E il quinto è l'ambito di blocco non locale per chiusure: non ho mai trovato un modo semplice per spiegarlo. –

+0

+1 Bella risposta. –

2

Credo che Python utilizzi l'ambito delle funzioni per le variabili locali. Cioè, in qualsiasi funzione data, se assegni un valore a una variabile locale, sarà disponibile da quel momento in avanti all'interno di quella funzione fino a quando non ritorna. Pertanto, poiché entrambi i rami del codice sono garantiti da assegnare a a, non è necessario assegnare None a a inizialmente.

Si noti che quando è possibile accedere anche alle variabili dichiarate nelle funzioni esterne, in altre parole, Python ha delle chiusure.

def adder(first): 
    def add(second): 
     return first + second 

    return add 

Definisce una funzione denominata adder. Quando viene chiamato con un argomento first, restituirà una funzione che aggiunge qualsiasi argomento che riceve a first e restituisce tale valore. Per esempio:

add_two = adder(2) 
add_three = adder(3) 
add_two(4) # = 6 
add_three(4) # = 7 

Tuttavia, anche se è possibile leggere il valore dalla funzione esterna, non è possibile modificarlo (a differenza di molte altre lingue). Ad esempio, immagina di provare ad implementare un accumulatore. Si potrebbe scrivere un codice in questo modo:

def accumulator(): 
    total = 0 
    def add(number): 
     total += number 
     return total 
    return add 

Purtroppo, cercando di utilizzare questi risultati di codice in un messaggio di errore:

UnboundLocalError: local variable 'total' referenced before assignment 

Questo perché la linea total += number cerca di modificare il valore di total, che non può essere fatto in questo modo in Python.

+0

Puoi fare ciò che ti serve nell'esempio 'accumulator()' usando 'nonlocal' (nuovo in Python 3). –

0

Python non ha bisogno di variabili da dichiarare inizialmente, quindi è possibile dichiararlo e definirlo in punti arbitrari. E sì, l'ambito è l'ambito della funzione, quindi sarà visibile all'esterno dello if.

1

Non c'è alcun problema nell'assegnare la variabile nel blocco if.

In questo caso viene assegnato su entrambi i rami, quindi è possibile vederlo verrà definitivamente definito quando si arriva a stamparlo.

Se uno dei rami non ha assegnato a a poi un'eccezione NameError sarebbe alzare quando si tenta di stampare dopo quel ramo

0

Sono abbastanza un programmatore alle prime armi, ma per quello che so, in pitone le variabili private non esistono. vedere private variables nella documentazione di Python per una discussione dettagliata.

informazioni utili si possono trovare anche nella sezione "ambiti e spazi dei nomi" sulla stessa pagina.

personalmente, scrivo il codice come quello che hai postato praticamente ogni giorno, soprattutto quando la condizione si basa per ottenere input da parte dell'utente, per esempio

if len(sys.argv)==2: 
    f = open(sys.argv[1], 'r') 
else: 
    print ('provide input file') 

faccio dichiarare le variabili prima di utilizzarli per i tipi strutturati per esempio dichiaro una lista vuota prima di aggiungere i suoi elementi all'interno di un ciclo.

spero che sia d'aiuto.

Problemi correlati