2012-09-09 13 views

risposta

15

seguito le solleva l'execption:

def foo(): 
    spam = 'eggs' 
    def bar(): 
     print spam 
    del spam 

perché la variabile spam viene usata nel campo chiuso della bar:

>>> def foo(): 
...  spam = 'eggs' 
...  def bar(): 
...   print spam 
...  del spam 
... 
SyntaxError: can not delete variable 'spam' referenced in nested scope 

Python rileva che spam viene fatto riferimento in bar ma non lo fa assegnare qualsiasi cosa a quella variabile, quindi la ricerca nell'ambiente circostante di foo. Il numero è assegnato a , rendendo l'istruzione del spam un errore di sintassi.

Questa limitazione è stata rimossa in Python 3.2; ora sei responsabile di non eliminare te stesso le variabili nidificate; si otterrà un errore di runtime (NameError) invece:

>>> def foo(): 
...  spam = 'eggs' 
...  def bar(): 
...   print(spam) 
...  del spam 
...  bar() 
... 
>>> foo() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 6, in foo 
    File "<stdin>", line 4, in bar 
NameError: free variable 'spam' referenced before assignment in enclosing scope 
4

Un esempio può essere questo:

>>> def outer(): 
...  x = 0 
...  y = (x for i in range(10)) 
...  del x 
... 
SyntaxError: can not delete variable 'x' referenced in nested scope 

In pratica significa che non è possibile eliminare le variabili che vengono utilizzati in blocchi interni (in quel caso il genexp).

Si noti che questo si applica per python < = 2.7.xe python < 3.2. In python3.2 che è esso non genera errore di sintassi:

>>> def outer(): 
...  x = 0 
...  y = (x for i in range(10)) 
...  del x 
... 
>>> 

Vedi this collegamento per tutta la storia del cambiamento.

Credo che i semanthics python3.2 è più corretta, perché se si scrive lo stesso codice di fuori di una funzione che funziona:

#python2.7 
>>> x = 0 
>>> y = (x for i in range(10)) 
>>> del x 
>>> y.next()  #this is what I'd expect: NameError at Runtime 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in <genexpr> 
NameError: global name 'x' is not defined 

Mentre mettendo lo stesso codice in una funzione, non solo cambia un'eccezione ma l'errore è in fase di compilazione.