What's up with rebinding assignment?

Jeff Epler jepler at unpythonic.net
Fri Mar 21 15:24:56 CET 2003


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
operations are simple C array indexing when executed, and if that's
true, I don't see why the cell-setting instruction wouldn't be.

Jeff





More information about the Python-list mailing list