Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python variable naming/binding confusion

I am relatively new to Python development, and in reading through the language documentation, I came across a line that read:

It is illegal to unbind a name that is referenced by an enclosing scope; the compiler will report a SyntaxError.

So in a learning exercise, I am trying to create this error in the interactive shell, but I haven't been able to find a way to do so. I am using Python v2.7.3, so using the nonlocal keyword like

def outer():
  a=5
  def inner():
     nonlocal a
     print(a)
     del a

is not an option, and without using nonlocal, when Python sees del a in the inner function, it interprets it as a local variable that has not been bound and throws an UnboundLocalError exception.

Obviously there is an exception to this rule with regards to global variables, so how can I create a situation where I am "illegally" unbinding a variable name that is being referenced by an enclosing scope?

like image 503
Default Avatar asked Mar 11 '13 15:03

Default


1 Answers

The deletion has to take place in the outer scope:

>>> def foo():
...     a = 5
...     def bar():
...         return a
...     del a
... 
SyntaxError: can not delete variable 'a' referenced in nested scope

The compile-time restriction has been removed in Python 3:

$ python3.3
Python 3.3.0 (default, Sep 29 2012, 08:16:08) 
[GCC 4.2.1 Compatible Apple Clang 3.1 (tags/Apple/clang-318.0.58)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def foo():
...     a = 5
...     def bar():
...         return a
...     del a
...     return bar
... 
>>>

Instead, a NameError is raised when you try to refer to a:

>>> foo()()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in bar
NameError: free variable 'a' referenced before assignment in enclosing scope

I am tempted to file a documentation bug here. For Python 2, the documentation is misleading; it is deleting a variable used in a nested scope that triggers the compile-time error, and the error is no longer raised at all in Python 3.

like image 93
Martijn Pieters Avatar answered Sep 21 '22 16:09

Martijn Pieters