Intercept operator lookup on metaclass

У меня есть класс, в котором нужно сделать некоторую магию с каждым оператором, например __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

Просто для справки, я не хочу знать другой способ сделать то же самое (я не буду объявлять каждый оператор в классе... это будет скучно, и тот подход, который у меня есть, работает довольно хорошо :)). Я хочу знать, как перехватить поиск атрибутов у оператора

8
задан JBernardo 26 December 2011 в 22:07
поделиться