Easy questions from a python beginner

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Wed Jul 14 12:59:27 EDT 2010


On Wed, 14 Jul 2010 09:06:34 -0700, Ethan Furman wrote:

> Alf P. Steinbach /Usenet wrote:
[...]
>> Clearly when the exception is raised, referring to the variable, the
>> variable exists.
> 
> You are the only one spouting nonsense.  Have you tried this?
> 
> --> def foo():
> ...   print locals()
> ...   blah = 'interesting'
> ...   print locals()
> ...
> --> foo()
> {}
> {'blah': 'interesting'}
> 
> As can be clearly seen, blah does not exist before the assignment -- the
>   *name* blah has not been *bound* to an object yet, which is also what
> the error message says when you try to use it before it exists:

While I agree with your basic position that, in a meaningful sense, 
"blah" does not exist before it is assigned to, your explanation is 
invalid.

In CPython, local variables in functions are optimised into pre-allocated 
slots. locals() is a *copy* of the actual locals, and any locals which 
are allocated but not defined are suppressed from the dict.

>>> def f():
...     x = 5
...     if y:
...             z = 1
...     return x+z
...
>>> f.func_code.co_nlocals
2
>>> f.func_code.co_freevars
()
>>> f.func_code.co_varnames
('x', 'z')

More here:
http://tech.blog.aknin.name/2010/07/03/pythons-innards-code-objects/

You'll notice that in the sense of having space allocated for them in the 
code object, the variables already exist before the function has even 
been executed. But of course that's not the only sense, or even the most 
important one. I would argue that, in a very real sense, if you call f() 
with the global y set to False, that *semantically* the local z doesn't 
exist, even if the error message says different:

> UnboundLocalError: local variable 'z' referenced before assignment


-- 
Steven




More information about the Python-list mailing list