У меня есть класс, который нужно сделать с каждым оператором, как __add__
, __sub__
и так далее.Перехват поиска оператора на метаклассе
Вместо создания каждой функции в классе у меня есть метакласс, который определяет каждый оператор в модуле оператора.
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
Кроме того, «функция», в результате должен быть способ, связанный с экземпляром используется.
Любые идеи о том, как я могу перехватить этот поиск? Я не знаю, ясно ли, что я хочу делать.
Для тех сомнению, почему мне нужно сделать такого рода вещи, проверить полный код here. Это инструмент для генерации функций (только для удовольствия), который может работать как замена для lambda
s.
Пример:
>>> f = FuncBuilder()
>>> g = f ** 2
>>> g(10)
100
>>> g
<var [('pow', 2)]>
Просто для записи, я не хочу знать, еще один способ сделать то же самое (я не буду объявлять каждый оператор в классе ... что будет скучно, и подход у меня работает очень хорошо :). Я хочу знать, как перехватить поиск атрибута от оператора.
«У меня есть класс, который должен сделать магию с каждым оператором» - Почему? Похоже, вы лаяете очень сложное дерево ... –
@ LennartRegebro Я пишу генератор функций, используя операторы на каком-то объекте. 'f = FuncBuilder(); g = f ** 2 + 1; g (10) == 101'. Это не очень полезно (много вызовов функций), но несколько полезно использовать: D – JBernardo
@ LennartRegebro Я разместил полный код. – JBernardo