Modifying func_closure

Jacek Generowicz jacek.generowicz at cern.ch
Mon Jul 12 07:25:38 EDT 2004


Peter Otten <__peter__ at web.de> writes:

> Jacek Generowicz wrote:
> 
> >>> b) The closure is much clearer, shorter and more convenient.
> >>> I have so many of these things that using the class version
> >>> would make the code a real mess.
> 
> Does the following count as a closure, a class version, or a "real mess"?
>
> class Bunch:
>     def __init__(self, kw):
>         self.__dict__.update(kw)
> 
> def make(a):
>     c = 33
>     self = Bunch(locals())
>     def update(delta):
>             self.a += delta
>             return self.c, self.a
>     return update
> 
> f = make(10)
> for i in range(3):
>     print f(i)

Well, the use of the keyword "class" should be a big hint to the fact
that it counts as "class version" ...
    
    class Bunch:
        def __init__(self, kw):
            self.__dict__.update(kw)
    
    def make(a):
        c = 33
        self = Bunch(locals())
        def update(self, delta):
                self.a += delta
                return self.c, self.a
        return update
    
    class foo:
        update = make(10)
    
    f = foo()
    f.update(3)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "/usr/tmp/python-BxF-To", line 17, in ?
        f.update(3)
      File "/usr/tmp/python-BxF-To", line 9, in update
        self.a += delta
    AttributeError: foo instance has no attribute 'a'

... and the above should be a hint suggesting that by the time you've
got it working properly[*], it will be a big mess. (To those
comfortable with nested lexical scopes, it's already a big mess: in
nested lexical scoping, shadowing is a feature; in instance methods
shadowing is a PITA.)

> Put another way, could it be that the need for closures is just a
> request to get rid of self in disguise?

No. I like self. Self is all fine and well and beautiful, and I am
glad that it is there ... when I am implementing classes.

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'd also like Python not to treat builtin functions and pure Python
functions differently, but that's a different rant :-)

[*] The closure version (with closure mutablility hacked in[+]) just
    works:

      def cmake(a):
          c = 33
          a = [a]
          def update(self, delta):
              a[0] += delta
              return c, a[0]
          return update
      
      class foo:
          update = cmake(10)
      
      f = foo()
      f.update(3)  # -> (33, 13)


[+] Before anyone cites this as an argument against the closure
    version being clear ... this is exactly the whole point of the
    thread: wouldn't it be useful to fix closures and make them
    mutable.



More information about the Python-list mailing list