[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Re: Another dumb scope question for a closure.

Mike Meyer

1/9/2008 8:24:00 PM

On Wed, 9 Jan 2008 13:47:30 -0500 (EST) "Steven W. Orr" <steveo@syslang.net> wrote:

> So sorry because I know I'm doing something wrong.
>
> 574 > cat c2.py
> #! /usr/local/bin/python2.4
>
> def inc(jj):
> def dummy():
> jj = jj + 1
> return jj
> return dummy
>
> h = inc(33)
> print 'h() = ', h()
> 575 > c2.py
> h() =
> Traceback (most recent call last):
> File "./c2.py", line 10, in ?
> print 'h() = ', h()
> File "./c2.py", line 5, in dummy
> jj = jj + 1
> UnboundLocalError: local variable 'jj' referenced before assignment
>
> I could have sworn I was allowed to do this. How do I fix it?

Nope. This is one of the things that makes lisper's complain that
Python doesn't have "real closures": you can't rebind names outside
your own scope (except via global, which won't work here).

Using a class is the canonical way to hold state. However, any of the
standard hacks for working around binding issues work. For instance:

>>> def inc(jj):
.... def dummy():
.... box[0] = box[0] + 1
.... return box[0]
.... box = [jj]
.... return dummy
....
>>> h = inc(33)
>>> h()
34

<mike

--
Mike Meyer <mwm@mired.org> http://www.mired.org/consu...
Independent Network/Unix/Perforce consultant, email for more information.
1 Answer

Arnaud Delobelle

1/9/2008 8:52:00 PM

0

On Jan 9, 8:24 pm, Mike Meyer <m...@mired.org> wrote:
> On Wed, 9 Jan 2008 13:47:30 -0500 (EST) "Steven W. Orr" <ste...@syslang.net> wrote:
>
>
>
> > So sorry because I know I'm doing something wrong.
>
> > 574 > cat c2.py
> > #! /usr/local/bin/python2.4
>
> > def inc(jj):
> >      def dummy():
> >          jj = jj + 1
> >          return jj
> >      return dummy
>
> > h = inc(33)
> > print 'h() = ', h()
> > 575 > c2.py
> > h() =
> > Traceback (most recent call last):
> >    File "./c2.py", line 10, in ?
> >      print 'h() = ', h()
> >    File "./c2.py", line 5, in dummy
> >      jj = jj + 1
> > UnboundLocalError: local variable 'jj' referenced before assignment
>
> > I could have sworn I was allowed to do this. How do I fix it?
>
> Nope. This is one of the things that makes lisper's complain that
> Python doesn't have "real closures": you can't rebind names outside
> your own scope (except via global, which won't work here).

Note that the 'nonlocal' keyword solves this problem in py3k:

Python 3.0a1+ (py3k:59330, Dec 4 2007, 18:44:39)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def inc(j):
... def f():
... nonlocal j
... j += 1
... return j
... return f
...
>>> i = inc(3)
>>> i()
4
>>> i()
5
>>>


--
Arnaud