Как создать декоратор в классе?
Вот упрощенный фрагмент моего кода, который я не понимаю, почему не работает:
class Class:
def __init__(self, var):
self.var = var
def decorator(self, function):
function()
print(self.var+1)
@decorator
def fun(self):
print('*Function*')
Python говорит:
Traceback (most recent call last):
File "test2.py", line 1, in <module>
class Class:
File "test2.py", line 10, in Class
def fun(self):
TypeError: decorator() missing 1 required positional argument: 'function'
Важно, чтобы описание декоратора было внутри класса, так как он использует self.переменные. Разве так нельзя сделать? А без синтаксического сахара я вообще не понимаю, как это реализовать. Разве что после создания экземпляра класса делать так:
cl = Class(2)
cl.fun = cl.decorator(cl.fun)
Но тогда теряется смысл использования этого декоратора
Ответы (1 шт):
Когда вы назначаете декоратор внутри класса, вы напрямую обращаетесь к "unbound" функции decorator. Никакого контекста, связанного с инстансом у неё ещё нет. Это не Class.decorator и не Class().decorator. Поэтому оборачиваемая функция в неё передаётся первым аргументом(попадает в self).
Именно поэтому интерпретатор сообщает о пропущенном параметре function
Если вы хотите декорировать методы, то можно вынести декоратор из объявления класса:
def dec(fn):
def f(self, *args, **kwargs):
fn(self, *args, **kwargs)
print(self.var)
return f
class C:
def __init__(self, var):
self.var = var
@dec
def bar(self):
print('bar')
c = C(42);
c.bar()
Хотя, с тем же успехом, можно внести функцию декоратора внутрь класса.
Вызываться она будет всё равно как статическая функция и будет торчать метод объекта, который нельзя вызывать(т.к. при вызове будет передан объект C в качестве fn):
class C:
def __init__(self, var):
self.var = var
def _dec(fn):
def f(self, *args, **kwargs):
fn(self, *args, **kwargs)
print(self.var)
return f
@_dec
def bar(self):
print('bar')
c = C(42);
c.bar()