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