[Python-Dev] functools.compose to chain functions together
Scott Dial
scott+python-dev at scottdial.com
Mon Aug 17 09:50:04 CEST 2009
Greg Ewing wrote:
> Jason R. Coombs wrote:
>> I had a use case that was compelling enough that I thought there
>> should be something in functools to do what I wanted.
>
> I think this is one of those things that a small minority of
> people would use frequently, but everyone else would use
> very rarely or never. The decision on whether to include
> something in the stdlib needs to be based on the wider
> picture.
>
> In this case, it's trivial to write your own if you want
> it. As they say, "not every one-line function needs to
> be in the stdlib".
>
I have never found these arguments compelling. They are obviously not
true (e.g., itertools.compress()[1] added in 2.7/3.1), and so what I
really hear is: "I don't like it and I outrank you."
I can't help invoke part of PEP309's justification for
functools.partial()[2]:
"""
I agree that lambda is usually good enough, just not always. And I want
the possibility of useful introspection and subclassing.
"""
The same reasoning would seem to apply here. In the OP's example, the
meta-decorator becomes opaque due to the use of a lambda. If one could
introspect a compose(), then introspection tools could actually know the
set of decorators being applied. As it is, the "preferred" method of
using a lambda actually makes it quite hard to know anything.
class compose():
def __init__(self, *funcs):
if not funcs:
raise ValueError(funcs)
self.funcs = funcs
def __call__(self, *args, **kwargs):
v = self.funcs[-1](*args, **kwargs)
for func in reversed(self.funcs[:-1]):
v = func(v)
return v
meta = functools.compose(decorator_a, decorator_b)
print meta.funcs
meta = lambda f: decorator_a(decorator_b(f))
# impossible, short of disassembling the lambda
-Scott
[1] http://docs.python.org/3.1/library/itertools.html#itertools.compress
"""
def compress(data, selectors):
# compress('ABCDEF', [1,0,1,0,1,1]) --> A C E F
return (d for d, s in zip(data, selectors) if s)
"""
More information about the Python-Dev
mailing list