Function closure inconsistency

Dave Angel davea at ieee.org
Fri Jul 23 15:51:45 EDT 2010


SeanMon wrote:
> I was playing around with Python functions returning functions and the
> scope rules for variables, and encountered this weird behavior that I
> can't figure out.
>
> Why does f1() leave x unbound, but f2() does not?
>
> def f1():
>     x = 0
>     def g():
>         x += 1
>         return x
>     return g1
>
> def f2():
>     x = []
>     def g():
>         x.append(0)
>         return x
>     return g
>
> a = f1()
> b = f2()
>
> a() #UnboundLocalError: local variable 'x' referenced before
> assignment
> b() #No error, [0] returned
> b() #No error, [0, 0] returned
>
>   
Your example is more complex than needed.  The symptom doesn't need a 
function closure.

 >>> def g():
...    x += 1
...    return x
...
 >>> g()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in g
UnboundLocalError: local variable 'x' referenced before assignment
 >>> def f():
...    x.append(0)
...    return x
...
 >>> x = [3,5]
 >>> f()
[3, 5, 0]
 >>>


The difference between the functions is that in the first case, x is 
reassigned; therefore it's a local.  But it's not defined before that 
line, so you get the ref before assign error.

In the second case, append() is an in-place operation, and doesn't 
create a local variable.

DaveA




More information about the Python-list mailing list