Prev: time between now and the next 2:30 am?
Next: A portable LISP interpreter that includes all the major list-processing functions is described. A complete, annotated listing of the program's code, written in PASCAL, is included.
From: SeanMon on 23 Jul 2010 14:30 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
From: Benjamin Kaplan on 23 Jul 2010 14:49 On Fri, Jul 23, 2010 at 11:30 AM, SeanMon <smono927(a)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
From: Dave Angel on 23 Jul 2010 15:51 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
From: Terry Reedy on 23 Jul 2010 18:21
On 7/23/2010 2:30 PM, 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(): In 3.x, add nonlocal x > x += 1 > return x > return g1 You meant g def f1(): x = 0 def g(): nonlocal x x += 1 return x return g f=f1() print(f()) print(f()) print(f()) print(f()) 1 2 3 4 -- Terry Jan Reedy |