[Tutor] function algebra (was: Re: Python vs. Ruby)
Abel Daniel
abli at freemail.hu
Fri Oct 31 09:48:00 EST 2003
[ me, a bit earlier: ]
> Finishing up (adding other stuff from
> http://python.org/doc/current/ref/numeric-types.html
> and handling things like "Fun(math.sin) + 5" ) are left as an exercise
> to the reader. :)
I couldn't stand not doing it :)
It's a bit less readable, but should handle any numerical operation.
It also handles the case of "f=Fun(math.sin) + 5" (so that in this case
f(x) will be math.sin(x) + 5), plus it does composition:
>>> cos=Fun(math.cos)
>>> cs = cos.compose(math.sin)
>>> cs(1)
0.66636674539288054
>>> math.cos(math.sin(1))
0.66636674539288054
>>>
------8<-------------
# we don't need to add __iadd__ and such as those fall back to using
# __add__ etc.
unary_operators=['__neg__', '__pos__', '__abs__', '__invert__',
'__complex__', '__int__', '__long__', '__float__',
'__oct__', '__hex__']
binary_operators=['__add__','__sub__','__mul__', '__floordiv__',
'__mod__', '__divmod__', '__lshift__', '__rshift__',
'__and__', '__xor__', '__or__', '__radd__',
'__rsub__', '__rmul__', '__rdiv__', '__rtruediv__',
'__rfloordiv__', '__rmod__', '__rdivmod__',
'__rpow__', '__rlshift__', '__rrshift__',
'__rand__', '__rxor__', '__ror__']
ternary_operators=['__pow__']
class Fun:
def __init__(self, func):
self.func=func
def __call__(self, *a, **kw):
return self.func(*a, **kw)
def compose(self, other):
def f(*a, **kw):
return self.func(other(*a, **kw))
return Fun(f)
def __getattr__(self, name):
if name in binary_operators:
return self.binary_operation(name)
elif name in unary_operators:
return self.unary_operation(name)
elif name in ternary_operators:
return self.ternary_operation(name)
else:
raise AttributeError
def binary_operation(self, name):
def ff(other):
def f(*a, **kw):
return getattr(self.func(*a, **kw), name)(other(*a, **kw))
return Fun(f)
return ff
def unary_operation(self, name):
def ff():
def f(*a, **kw):
return getattr(self.func(*a, **kw), name)()
return Fun(f)
return ff
def ternary_operation(self, name):
def ff(other, *args):
def f(*a, **kw):
return getattr(self.func(*a, **kw), name)(other(*a, **kw),
*args)
return Fun(f)
return ff
def __coerce__(self, other):
if callable(other):
return self, other
else:
return self, lambda x: other
-----------8<-------------------
--
Abel Daniel
More information about the Tutor
mailing list