Modifying func_closure

Jacek Generowicz jacek.generowicz at cern.ch
Mon Jul 12 09:58:18 EDT 2004


Peter Otten <__peter__ at web.de> writes:

> Jacek Generowicz wrote:
> 
> [me]
> >> def make(a):
> >>     c = 33
> >>     self = Bunch(locals())
> >>     def update(delta):
> >>             self.a += delta
> >>             return self.c, self.a
> >>     return update
> 
> [Jacek]
> >     def make(a):
> >         c = 33
> >         self = Bunch(locals())
> >         def update(self, delta):
> >                 self.a += delta
> >                 return self.c, self.a
> >         return update
> 
> Did you spot the difference? 

Not only did I spot it, I deliberately put it there :-) (I trust that
it is obvious to casual onlookers that it wouldn't have worked without
the inserted difference, either.) (I admit that the bug was not
deliberate though (which probably only goes to support my point that
this approach is unclear, messy, error-prone ...))

> Now let's change the misleading name 'self' into 'outer':

... thereby installing the lexical scope plumbing yourself ...

> class Bunch:
>     def __init__(self, kw):
>         self.__dict__.update(kw)
> 
> 
> def make(a):
>     c = 33
>     outer = Bunch(locals())
>     def update(self, delta):
>             outer.a += delta
>             return outer.c, outer.a
>     return update

Which is a mess compared to

  def make(a):
      c = 33
      a = [a]
      def update(self, delta):
          a[0] += delta
          return c, a[0]
  
... and a _real_ mess compared to

  def make(a):
      c = 33
      def update(self, delta):
          lexical a  # To pick one possible syntax
          a += delta
          return c, a
  
<0.5 wink>

> I'm not sure why, if you're using a class anyway, you aren't using
> it to store method state, too.

Because the class which creates the method is not the one which gets
to keep it. 

Because the enclosed state is not an attribute of the instance, or of
its class: it's an attribute of the method.

(Those are the two reasons which spring to mind immediately, there may
well be more.)

> > However, when I'm implementing functions, I'd really like to be able
> > to implement functions, and not have to try to hack around here and
> > there trying to make classes or their instances behave like functions,
> > wherever I need them to behave like functcions ... even when my
> > function happens to carry some state around.
> 
> I've no principal objections, I just didn't spot a proposition that
> integrates nicely with the rest of the language.

The "global" keyword essentially exists to make global state mutable,
so a similar "lexical" keyword to make enclosed state mutable, would
probably integrate nicely. We could do with just one keyword for the
whole lot, but "global" is a poor name, if it is to include lexical
scopes too (not to mention backwards compatibility issues.)

> > (I'd also like Python not to treat builtin functions and pure Python
> > functions differently, but that's a different rant :-)
> 
> Here I'm with you.

I have a vague recollection of someone, somewhere, mentioning that
this might change in 2.4 ... but that's probably just a product of my
optimistic imagination.



More information about the Python-list mailing list