下面是一類裝飾做它,因爲我想向你描述的註釋的一個例子。我在你的問題中填入了一些未定義的引用,並使用了一個超簡化版本的cache_response
函數裝飾器,但希望這會足夠具體地傳達這個想法,以便能夠將它適用於真實的代碼。
import inspect
import types
class Constructor(object):
def __init__(self, memoize_for_request=True, params=None):
self.memoize_for_request = memoize_for_request
self.params = params
def __call__(self):
def key_func():
print('key_func called with params:')
for k, v in self.params.items():
print(' {}: {!r}'.format(k, v))
key_func()
def cache_response(key_func):
def decorator(fn):
def decorated(*args, **kwargs):
key_func()
fn(*args, **kwargs)
return decorated
return decorator
def example_class_decorator(cls):
key_func = Constructor( # define key_func here using cls.key
memoize_for_request=True,
params={'updated_at': cls.key} # use decorated class's attribute
)
# create and apply cache_response decorator to marked methods
# (in Python 3 use types.FunctionType instead of types.UnboundMethodType)
decorator = cache_response(key_func)
for name, fn in inspect.getmembers(cls):
if isinstance(fn, types.UnboundMethodType) and hasattr(fn, 'marked'):
setattr(cls, name, decorator(fn))
return cls
def decorate_me(fn):
setattr(fn, 'marked', 1)
return fn
class CacheMix(object):
def __init__(self, *args, **kwargs):
super(CacheMix, self).__init__(*args, **kwargs)
@decorate_me
def list(self, *args, **kwargs):
classname = self.__class__.__name__
print('list() method of {} object called'.format(classname))
@example_class_decorator
class ListView(CacheMix):
key = 'test_key'
listview = ListView()
listview.list()
輸出:
key_func called with params:
updated_at: 'test_key'
list() method of ListView object called
有沒有'self'根本不被創建時類對象,重新考慮你的方法,也解決了壓痕。 –
如果你展示了裝飾器的代碼,它將會有所幫助 - 正如將知道什麼聲明導致錯誤消息一樣。 – martineau
@AshwiniChaudhary如果是這樣的話,無論如何要在init中創建裝飾器?即''self.list = cache_response(key_func)(type(self).list)'' – Prometheus