В этот вопрос Я задал вопрос об операторе композиции функций в Python. @ Philip Tzou предложил следующий код, который выполняет эту работу.
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)
Я добавил следующие функции.
def __mul__(self, other):
return lambda *args, **kw: self.func(other.func(*args, **kw))
def __gt__(self, other):
return lambda *args, **kw: self.func(other.func(*args, **kw))
С этими дополнениями можно использовать @
, *
и >
в качестве операторов для составления функций. Например, можно написать print((add1 @ add2)(5), (add1 * add2)(5), (add1 > add2)(5))
и получить # 8 8 8
. (PyCharm жалуется, что логическое значение не вызывается для (add1 > add2)(5)
. Но оно все еще работает.)
Тем не менее, я хотел использовать .
в качестве оператора композиции функций. Поэтому я добавил
def __getattribute__(self, other):
return lambda *args, **kw: self.func(other.func(*args, **kw))
(Обратите внимание, что это нарушает update_wrapper
, что может быть удалено ради этого вопроса.)
Когда я запускаю print((add1 . add2)(5))
, я получаю эту ошибку во время выполнения: AttributeError: 'str' object has no attribute 'func'
. Оказывается (очевидно), что аргументы __getattribute__
преобразуются в строки перед передачей в __getattribute__
.
Есть ли способ обойти это преобразование? Или я неправильно диагностирую проблему, и какой-то другой подход будет работать?