Can't extend function type
Christopher Subich
csubich.spam.block at spam.subich.block.com
Fri Oct 7 08:59:30 EDT 2005
Diez B. Roggisch wrote:
> Paul Rubin wrote:
>
>> Oh well. I had wanted to be able to define two functions f and g, and
>> have f*g be the composition of f and g.
>>
>> >>> func_type = type(lambda: None)
>> >>> class composable_function(func_type):
>> ... def __mult__(f,g):
>> ... def c(*args, **kw):
>> ... return f(g(*args, **kw))
>> ... return c
>> ...
>> Traceback (most recent call last):
>> File "<stdin>", line 1, in ?
>> TypeError: Error when calling the metaclass bases
>> type 'function' is not an acceptable base type
>> >>>
>>
>> Seems like a wart to me.
>
> So the only way to achieve this with current semantics is to make f anf
> g objects with a call methods. In that very moment, you're done - as
> extending from object is no problem :)
>
>
> class ComposeableFunction(object):
>
> def __call__(self, *args, **kwargs):
> return self.second(self.first(*args, **kwargs))
Note, with a little bit of massaging, you can turn ComposableFunction
into a decorator, for more natural function definition:
(Untested, I'm not on a system with Py2.4 at the moment):
class Composable(object):
def __init__(self,f):
self.callable = f
def __call__(self,*args, **kwargs):
return self.callable(*args, **kwargs)
def __mul__(self,other):
return Composable(lambda (*a, **kwa): self.callable(other(*a,
**kwa)))
Usage:
@Composable
def f(x):
return x**2
@Composable
def g(x):
return x+1
# And we shouldn't even need a @Composable on the last in the sequence
def h(x):
return x/2.0
>>>f(1)
1
>>>(f*g)(1)
4
>>>(f*g*h)(2)
4
This might not combine neatly with methods, however; the bound/unbound
method magic is still mostly voodoo to me.
More information about the Python-list
mailing list