In this question I asked about function composition. @Philip Tzou offered the following code, which does the job.
import functools
class Composable:
def __init__(self, func):
self.func = func
functools.update_wrapper(self, func)
def __matmul__(self, other):
return lambda *args, **kw: self.func(other.func(*args, **kw))
def __call__(self, *args, **kw):
return self.func(*args, **kw)
I attempted to turn this into a function:
from functools import wraps
def composable(func):
@wraps(func)
def wrapper(*args, **kw):
return func(*args, **kw)
def __matmul__(other):
return lambda *args, **kw: func(other(*args, **kw))
wrapper.__matmul__ = __matmul__
return wrapper
When I run it I get this result.
print((add1.__matmul__(add2))(5))
# => 8
So __matmul__
does its job. But,
print((add1 @ add2)(5))
# => TypeError: unsupported operand type(s) for @: 'function' and 'function'
The system doesn't recognize that @
can handle two functions.
Why didn't this happen with the class decorator? And, is there a fix for it?
Thanks.