no re-binding of nested-scope locals, no re-binding in lambda, no,,, {was Re: lambda)

Alex Martelli aleaxit at yahoo.com
Thu May 24 09:03:43 EDT 2001


"Roman Suzi" <rnd at onego.ru> writes:
    ...
> > As was noted in another post, nested scopes don't let you REBIND
> > the local variables of the function you're nested in -- lambdas
> > can't rebind anything anyhow, of course -- well I guess one COULD
> > use an elegant and readable construct such as:
> > 
> >     lambda x: setattr(sys.module[__name__], 'k', k+x) or k
> 
> If counters are so common in the application in question, why not to:
> 
> class counter:

Sure, it's easy enough to avoid doing any re-binding if you code
suitable class-objects and provide them with suitable methods.  A
more general approach might be:

class data:
    def __init__(self, initval=None):
        self.val = initval
    def set(self, val):
        self.val = val
        return val
    def get(self):
        return self.val
    # and possibly others, but these suffice

With this, you can work around ANY of the Python limitations of
the form "I can't rebind [whatever] in the context [whatever]",
just by using a data instance and calling its .set method.  You
can see this as hiding the re-binding assignment statement into
a callable method, so it can fit into an expression.  Or, you
COULD call it cheating (and I wouldn't argue, but...:-).


E.g., people who pine for C's

while((x=next_val()) { bloop(x); }

can now code:

x=data()
while x.set(next_val()): bloop(x.get())

which is why I've slyly had .set return what it does set... to
avoid, if .set() returned None, having to code this as
    while x.set(next_val()) or x.get(): bloop(x.get())
which some traditionalists MIGHT see as obfuscated-ish...:-).


So, if you have your "D=data(0)" helper variable somewhere,
    lambda x: D.set(x+D.get())
or similar constructs will see you home.


If somebody whines "no far using classes", we can do without
them, of course, just use a LIST...:

K = [0]
    ...
lambda x: operator.setitem(K,0,K[0]+x) or K[0]

and if module operator is also forbidden to us, then surely
at least we'll be allowed to use list objects' methods and
simple built-in operators, no?  And therefore:

K = [0]
    ...
lambda x: K.append(K[0]+x) or K.remove(K[0]) or K[0]


There!  Now, *THAT* is readable, right?  "We don't need
no stinkin' re-binding..."!  Long live lambda loonies!-)


(And to think that some people bemoan the fact that
lists' modifying-methods, except .pop, return None...
why, how ELSE would we be empowered to use 'or' as
an ersatz ';'...!?-)


Alex

[P.S.: do I get an entry in the sparsely-populated roster
of 'Obfuscated Python' candidates thanks to this latest
lambda up there...?-)]






More information about the Python-list mailing list