Function closure inconsistency

Benjamin Kaplan benjamin.kaplan at case.edu
Fri Jul 23 14:49:52 EDT 2010


On Fri, Jul 23, 2010 at 11:30 AM, SeanMon <smono927 at gmail.com> 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
> --



It's not closure related at all. Same thing happens at the module level.

x = 0
def f1() :
   x += 1
#gives UnboundLocalError

x = []
def f2() :
   x.append(1)
#succeeds.

The reason for it is that if you have any assignments to the variable
in the function, Python creates a new local variable for it. x += 1 is
an assignment, not a modification. Python 2.x allows you to assign to
the global scope (using the global keyword) but support for assigning
to the outer function's scope wasn't added until Python 3 (with the
nonlocal keyword)


def f1():
   x = 0
   def g():
       nonlocal x
       x += 1
       return x
   return g1

>
> http://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list