Я хочу создать декоратор, который создает новую функцию / метод, который использует объект obj
. Если декорированный объект является функцией, то при создании функции необходимо создать экземпляр obj
. Если декорированный объект является методом, новый экземпляр obj
должен быть создан и привязан к каждому экземпляру класса, чей метод декорирован. Я не могу поместить украшение в __init__
, потому что декоратор изменяет документацию по функциям. У меня сейчас что-то вроде этого, но оно создается только time
один раз, а это не то, что я хочу:
__all__ = ['dec', 'A']
from time import time
import inspect
def dec(f):
obj = time() # want to set on object instantiation
def new(*args, **kwargs):
f(*args, **kwargs) # Validate against definition so it doesn't go
# out of sync
print obj
# ...
try:
d = inspect.getsourcelines(f)
except IOError:
d = "<unable to fetch definition>"
else:
d = d[0][1].rstrip('\n').rstrip(':').lstrip(' ').lstrip('def')
new.__doc__ = d + "\n" + (f.__doc__ or '')
return new
class A(object):
@dec
def f(self, x):
"""something"""
print '%s.f(%s)' % (self, x)
if __name__ == '__main__':
A().f(123)
A().f(123)
A().f(123)
Моя идея решить эту проблему - проверить, принимает ли объект, передаваемый декоратору, аргумент self
, если так, вернуть метод, который связывает obj
с self
, если его еще нет, и затем использовать self.obj
. И затем, если нет аргумента self
для объекта, переданного декоратору, просто создайте экземпляр obj
внутри декоратора и верните функцию, которая использует это.
Однако ... то, что я сказал, на самом деле не работает для меня, потому что в моем реальном декораторе я возвращаю объект, полученный из list
и имеющий атрибут __call__
. Более того, в реальном декораторе self
даже не определено в объектах, которые им декорируются, потому что они не используют свои переменные экземпляра (то, что я действительно украшаю, это просто события, которые нужно подписанные внешними объектами, события имеют задокументированные подписи).
Edit: На самом деле, если есть способ заставить экземпляр подкласса list
связываться с экземпляром, чтобы его атрибут __call__
неявно получал экземпляр класса (как в любом обычном методе экземпляра), это было бы идеально Решение, это было то, что я изначально пытался выяснить, как это сделать. Но, может быть, есть еще лучшее решение, так что мне не нужно определять украшенные методы с атрибутом self
? Либо идеально.