如何将self.key
传递给装饰者?
class CacheMix(object):
def __init__(self, *args, **kwargs):
super(CacheMix, self).__init__(*args, **kwargs)
key_func = Constructor(
memoize_for_request=True,
params={'updated_at': self.key}
)
@cache_response(key_func=key_func)
def list(self, *args, **kwargs):
pass
class ListView(CacheMix, generics.ListCreateAPIView):
key = 'test_key'
我收到错误:
'self' is not defined
答案 0 :(得分:3)
这是一个用类装饰器做的例子,我试图在评论中向你描述。我在你的问题中填写了一些未定义的引用,并使用了cache_response
函数装饰器的超简化版本,但希望这将足够具体地传达这个想法,使你能够使它适应你的真实代码。 / p>
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
答案 1 :(得分:1)
我刚刚发现,如果您这样编写装饰器函数:
def decorator(the_func):
@wraps(the_func)
def wrapper(*args, **kwargs):
the_func(*args, **kwargs)
return wrapper
并修饰任何以self为参数的方法,self将出现在args中。因此,您可以执行以下操作:
from functools import wraps
class myClass:
def __init__(self):
self.myValue = "Hello"
def decorator(the_func):
@wraps(the_func)
def wrapper(*args, **kwargs):
print(args[0].myValue)
the_func(*args, **kwargs)
return wrapper
@decorator
def myFunction(self):
print("World")
像平常一样打电话
foo = myClass()
foo.myFunction()
您应该获得
Hello
World