Имам клас, който трябва да направи малко магия с всеки оператор, като __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
Освен това получената "функция" трябва да бъде метод, обвързан с използвания екземпляр.
Някакви идеи как мога да прихвана това търсене? Не знам дали е ясно какво искам да правя.
За тези, които се питат защо ми трябват подобни неща, проверете пълния код тук. Това е инструмент за генериране на функции (само за забавление), които могат да работят като заместител на lambda
s.
Пример:
>>> f = FuncBuilder()
>>> g = f ** 2
>>> g(10)
100
>>> g
<var [('pow', 2)]>
Само за протокола, не искам да знам друг начин да направя същото (няма да декларирам всеки отделен оператор в класа... това ще бъде скучно и подходът, който имам, работи доста добре :). Искам да знам как да прихвана търсене на атрибут от оператор.
f = FuncBuilder(); g = f ** 2 + 1; g(10) == 101
. Не е нещо много полезно (много извиквания на функции), но е донякъде забавно за използване :D - person JBernardo   schedule 27.12.2011