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