What's up with rebinding assignment?
Alex Martelli
aleax at aleax.it
Sat Mar 22 05:44:18 EST 2003
Jeff Epler wrote:
> On Fri, Mar 21, 2003 at 01:53:25PM +0000, Des Small wrote:
>> I wouldn't use it here though, I'd use it for things like:
>>
>> def accumulator(val=0):
>> def inner_acc(amount):
>> lexical val
>> val = val + amount # I don't like +=, so there.
>> return val
>> return inner_acc(val)
>>
>> Since I don't expect the Python Priesthood (Bot-hood?) to be pleased
>> about this, I would want to market it as a less harmful version of
>> 'global'. It does do much the same thing, after all, and has much
>> the same conventions.
>
> You could also use it for a getter/setter factory:
> def make_getter_setter(initial_value=None):
> val = initial_value
>
> def get():
> return val
>
> def set(new_value):
> lexical val
> val = new_value
>
> return (get, set)
>
> However, in Python it's more natural to write these things as classes.
> For instance:
> class Accumulator:
> def __init__(self, val=0):
> self.val = val
>
> def __call__(self, amount):
> self.val = self.val + amount
> return self.val
>
> # Using lambda to prove I don't hate lisp
> accumulator = lambda val=0: Accumulator(val).__call__
>
> I suspect that the closure-based version would be slightly more
> efficient if it were writable, since the natural way to use Accumulator
> would create a bound method at each call, and the references to 'val' in
> __call__ are all namespace operations. I *think* that the cell
If I were tasked to write make_getter_setter in today's Python, I'd
probably code it as follows:
def make_getter_setter(initial_value=None):
class GetterSetter(object):
__slots__ = ['val']
def __init__(self, initial_value):
self.val = initial_value
def get(self):
return self.val
def set(self, new_value):
self.val = new_value
getterSetter = GetterSetter(initial_value)
return getterSetter.get, getterSetter.set
and similarly, for accumulator (which I think should be named
make_accumulator -- and I'm just guessing regarding what the
OP's code is meant to do, since, as he coded it, it just returns
a number that is twice the argument, 0 by default):
def make_accumulator(val = 0):
class Accumulate(object):
__slots__=['val']
def __init__(self, val):
self.val = val
def accumulate(self, val):
self.val += val
return self.val
return Accumulate(val).accumulate
Yes, you may be right that some tiny increase in efficiency might
be afforded by closure-based versions, if they were feasible. But
I'm not sure that such a tiny performance advantage would justify
complicating the language. GvR seems to be keen on ensuring the
"natural" way to bundle mutable-state and behavior together is by
using class instances, and to look askance on alternatives, though
then and again some such alternative does slip by him;-).
Alex
More information about the Python-list
mailing list