better lambda support in the future?

Bengt Richter bokr at oz.net
Sat Dec 18 04:50:34 EST 2004


On Sat, 18 Dec 2004 03:05:08 -0500, "Terry Reedy" <tjreedy at udel.edu> wrote:

>
>"Bengt Richter" <bokr at oz.net> wrote in message 
>news:41c3b477.357334890 at news.oz.net...
>> Looks like your standard pattern could be updated:
>>
>> >>> dispatch = {}
>> >>>
>> >>> def dispvia(name):
>> ...     def _(f, name=name):
>> ...         dispatch[name] = f
>> ...         return f
>> ...     return _
>> ...
>> >>> @dispvia('a')
>> ... def handle_a(): pass
>> ...
>> >>> @dispvia('b')
>> ... def handle_b(): pass
>> ...
>> >>> @dispvia('c')
>> ... def handle_c(): pass
>> ...
>> >>> for t in sorted(dispatch.items()): print '%5s: %r'%t
>> ...
>>     a: <function handle_a at 0x02EE8E9C>
>>     b: <function handle_b at 0x02EE8ED4>
>>     c: <function handle_c at 0x02EE8F0C>
>
>To avoid the redundancy of 'a' and '_a', etc, how about (untested):
>
>def dispvia(f):
>  dispatch[f.__name__.split('_')[1]] = f
>  return f
>
>? (Don't have 2.4 loaded yet)

That should work. Didn't want to retype ;-) I just wanted to get
to the experiment following -- did you notice that it takes the assignment
name from each "def dispatch ...", but it is actually re-assigning the returned dispatch
*dict* as the value, not a modified function? So no function was bound to any local name at
any time. Kind of faking the lambda thing, and allowing non-identifier keys if desired. E.g.,

 >>> dispatch = {}
 >>> def dispvia(name):
 ...     def _(f, name=name):
 ...         f.__name__ = repr(repr(name))
 ...         dispatch[name] = f
 ...         return dispatch
 ...     return _
 ...
 >>> for k in xrange(3):
 ...     @dispvia(k)
 ...     def dispatch(key=k): return key
 ...
 >>> for t in sorted(dispatch.items()): print '%5r: %r' % t
 ...
     0: <function '0' at 0x02EE8DBC>
     1: <function '1' at 0x02EE8DF4>
     2: <function '2' at 0x02EE8E2C>
 >>> for t in sorted(dispatch.items()): print '%r() => %r' % (t[1], t[1]())
 ...
 <function '0' at 0x02EE8DBC>() => 0
 <function '1' at 0x02EE8DF4>() => 1
 <function '2' at 0x02EE8E2C>() => 2

Sort of the effect of

 >>> dispatch2 = dict((k,lambda key=k:key) for k in xrange(3))
 >>> for t in sorted(dispatch2.items()): print '%20r:%r'%t
 ...
                    0:<function <lambda> at 0x02EE8FB4>
                    1:<function <lambda> at 0x02EF402C>
                    2:<function <lambda> at 0x02EF409C>

Oops, well it's not so pretty if you want to rename the lambdas in the same expression:

 >>> dispatch2 = dict((k, setattr(f, '__name__', repr(repr(k)))or f) for k,f in ((k,lambda key=k:key) for k in xrange(3)))
 >>> for t in sorted(dispatch2.items()): print '%20r:%r'%t
 ...
                    0:<function '0' at 0x02EE8FB4>
                    1:<function '1' at 0x02EF402C>
                    2:<function '2' at 0x02EF4064>
 >>> for t in sorted(dispatch.items()): print '%r() => %r' % (t[1], t[1]())
 ...
 <function '0' at 0x02EE8DBC>() => 0
 <function '1' at 0x02EE8DF4>() => 1
 <function '2' at 0x02EE8E2C>() => 2

;-/

Regards,
Bengt Richter



More information about the Python-list mailing list