У меня есть класс, в котором нужно сделать некоторую магию с каждым оператором, например __add__
, __sub__
и так далее.
Вместо того, чтобы создавать каждую функцию в классе, у меня есть метакласс, который определяет каждый оператор в модуле operator.
import operator
class MetaFuncBuilder(type):
def __init__(self, *args, **kw):
super().__init__(*args, **kw)
attr = '__{0}{1}__'
for op in (x for x in dir(operator) if not x.startswith('__')):
oper = getattr(operator, op)
# ... I have my magic replacement functions here
# `func` for `__operators__` and `__ioperators__`
# and `rfunc` for `__roperators__`
setattr(self, attr.format('', op), func)
setattr(self, attr.format('r', op), rfunc)
Подход работает хорошо, но я думаю, что было бы лучше, если бы я генерировал оператор замены только тогда, когда это необходимо.
Поиск операторов должен быть на метаклассе, потому что x + 1
выполняется как type(x).__add__(x,1)
вместо x.__add__(x,1)
, но это не отлавливается ни методами __getattr__
, ни __getattribute__
.
Это не работает:
class Meta(type):
def __getattr__(self, name):
if name in ['__add__', '__sub__', '__mul__', ...]:
func = lambda:... #generate magic function
return func
Также, результирующая "функция" должна быть методом, привязанным к используемому экземпляру.
Есть идеи, как я могу перехватить этот поиск? Я не знаю, понятно ли, что я хочу сделать.
Для тех, кто задается вопросом, зачем мне это нужно, посмотрите полный код здесь.
Это инструмент для генерации функций (просто для развлечения), которые могут работать как замена лямбдам
.
Пример:
>>> f = FuncBuilder()
>>> g = f ** 2
>>> g(10)
100
>>> g
Просто для справки, я не хочу знать другой способ сделать то же самое (я не буду объявлять каждый оператор в классе... это будет скучно, и тот подход, который у меня есть, работает довольно хорошо :)). Я хочу знать, как перехватить поиск атрибутов у оператора