У меня есть проблема с реализацией декоратора применяется в этом метаклассе декоратора я писал:метаклассов, которые украшают все методы класса с использованием два различные декораторы реализация
def decorateAll(decorator):
class MetaClassDecorator(type):
def __new__(meta, classname, supers, classdict):
for name, elem in classdict.items():
if type(elem) is FunctionType:
classdict[name] = decorator(classdict[name])
return type.__new__(meta, classname, supers, classdict)
return MetaClassDecorator
Это класс, в котором я использовал метаклассом:
class Account(object, metaclass=decorateAll(Counter)):
def __init__(self, initial_amount):
self.amount = initial_amount
def withdraw(self, towithdraw):
self.amount -= towithdraw
def deposit(self, todeposit):
self.amount += todeposit
def balance(self):
return self.amount
Все, кажется, прекрасно работает, когда я перехожу к украсьте метакласса декоратора реализован так:
def Counter(fun):
fun.count = 0
def wrapper(*args):
fun.count += 1
print("{0} Executed {1} times".format(fun.__name__, fun.count))
return fun(*args)
return wrapper
Но когда я использую декоратора реализован таким образом:
class Counter():
def __init__(self, fun):
self.fun = fun
self.count = 0
def __call__(self, *args, **kwargs):
print("args:", self, *args, **kwargs)
self.count += 1
print("{0} Executed {1} times".format(self.fun.__name__, self.count))
return self.fun(*args, **kwargs)
Я получил эту ошибку:
line 32, in __call__
return self.fun(*args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'initial_amount'
Почему? Использование двух декораторов с другими функциями не показывает мне проблем. Я думаю, что проблема связана с тем, что методы, которые я пытаюсь украсить, - это методы класса. Я что-то упускаю?
Когда, на ваш взгляд, удобнее использовать этот подход? – Nikaidoh
В вашем случае это уместно, потому что вы украшаете обычные ** методы ** (те, которые принимают 'self' в качестве первого параметра, т. Е. Они привязаны к экземпляру во время создания экземпляра). Альтернативой является возвращение другого объекта (а не 'functools.partial'), который содержит ссылку на экземпляр (' obj') и связан с дескриптором – mementum