[Python-ideas] variable binding [was lambda decorators]

Carl Johnson carl at carlsensei.com
Tue Feb 10 01:46:42 CET 2009


The proposal to add bind to the function definition is silly, since we  
can do the equivalent of def f(bind i, …) already using  
decorators:

 >>> class bind(object):
...     def __init__(self, *args, **kwargs):
...         self.args, self.kwargs = args, kwargs
...
...     def __call__(self, f):
...         def inner(*args, **kwargs):
...             return f(self, *args, **kwargs)
...         return inner
...
 >>> l = []
 >>> for i in range(10):
...     @bind(i)
...     def my_func(bound_vars, *args, **kwargs):
...         return bound_vars.args[0]
...     l.append(my_func)
...
 >>> [f() for f in l]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 >>> [f() for f in l]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Just put the bind decorator into functools and the problem is solved.  
This is better than the (UGLY!) default values hack, since in this  
case it is impossible for your caller to accidentally overwrite the  
value you wanted bound (or at least not without some stackframe  
manipulation, at which point you get what you deserve).

I also don't like Guido's proposed var and new keywords. With all due  
respect, it looks like JavaScript. Besides, we all ready have a  
perfectly good tool for adding new scopes: functions. Just use a  
decorator like this map_maker to make an imap of the for-loop you  
wanted to have a separate scope in.

 >>> class map_maker(object):
...     def __init__(self, f):
...         self.f = f
...
...     def __call__(self, seq):
...         return (self.f(item) for item in seq)
...
 >>> a = 1
 >>>
 >>> @map_maker
... def my_map(a):
...     print("Look ma, the letter a equals", a)
...
 >>> list(my_map(range(10)))
Look ma, the letter a equals 0
Look ma, the letter a equals 1
Look ma, the letter a equals 2
Look ma, the letter a equals 3
Look ma, the letter a equals 4
Look ma, the letter a equals 5
Look ma, the letter a equals 6
Look ma, the letter a equals 7
Look ma, the letter a equals 8
Look ma, the letter a equals 9
[None, None, None, None, None, None, None, None, None, None]
 >>>
 >>> a
1

So, my proposal is that the API of the bind decorator be cleaned up  
considerably then added to the functools. The map_maker API seems to  
be good enough and could also go into functools.

-- Carl



More information about the Python-ideas mailing list