2012-09-09 10 views

Respuesta

15

A continuación se plantea la execption:

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

porque la variable spam está siendo utilizado en el ámbito cerrado de bar:

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

Python detecta que se está haciendo referencia spam en bar pero no lo hace asigna algo a esa variable, por lo que busca en el ámbito circundante de foo. Se es asignado allí, por lo que la declaración del spam un error de sintaxis.

Esta limitación se eliminó en Python 3.2; usted es ahora responsable de no eliminar las variables anidadas usted mismo; obtendrá un error de ejecución (NameError) en su lugar:

>>> 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 ejemplo puede ser la siguiente:

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

Básicamente esto significa que no puede eliminar las variables que se utilizan en los bloques interiores (en ese caso el genexp).

Tenga en cuenta que esto se aplica a python < = 2.7.x y python < 3.2. En python3.2 Es que no plantea error de sintaxis:

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

Ver this vínculo para toda la historia del cambio.

creo que los semanthics python3.2 es más correcto ya que si se escribe el mismo código fuera de una función funciona:

#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 

Mientras se pone el mismo código en una función, no sólo cambia excepción, sino el error está en tiempo de compilación.