Curious case of UnboundLocalError

Peter Otten __peter__ at web.de
Sat Mar 31 06:25:54 EDT 2018


Johannes Bauer wrote:

> On 30.03.2018 13:25, Johannes Bauer wrote:
> 
>>> This mention of collections refers to ...
>>>
>>>> }
>>>> for (_, collections) in z.items():
>>>
>>> ... this local variable.
>> 
>> Yup, but why? I mean, at the point of definition of "z", the only
>> definition of "collections" that would be visible to the code would be
>> the globally imported module, would it not? How can the code know of the
>> local declaration that only comes *after*?
> 
> Now that I understand what's going on, this is a much clearer example:
> 
> import collections
> def foo():
> print(collections)
> collections = "BAR"
> foo()
> 
> I would have thought that during the "print", collections (because
> locally undefined) would expand the scope to global scope and refer to
> the module and only after the definition overwrites the binding with the
> local scope, collections would be "BAR".
> 
> But that's not the case. Huh! I wonder if I'm the last one to notice
> that -- it's never come up before for me, I think :-)

While you're at it -- the body of a class behaves the way you expected from 
a function:

>>> x = "outer"
>>> class A:
...     print(x)
...     x = "inner"
...     print(x)
... 
outer
inner

And here's an odd application for exec():

>>> x = "outer"
>>> def f():
...     exec("print(x)")
...     x = "inner"
...     exec("print(x)")
... 
>>> f()
outer
inner

Also:

$ cat tmp.py
x = "outer"
def f():
    print(x)
    exec("x = 'inner'")
    print(x)
f()
$ python2 tmp.py
outer
inner
$ python3 tmp.py
outer
outer





More information about the Python-list mailing list