2015-11-08 26 views
4

我如何將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

有沒有'self'根本不被創建時類對象,重新考慮你的方法,也解決了壓痕。 –

+0

如果你展示了裝飾器的代碼,它將會有所幫助 - 正如將知道什麼聲明導致錯誤消息一樣。 – martineau

+0

@AshwiniChaudhary如果是這樣的話,無論如何要在init中創建裝飾器?即''self.list = cache_response(key_func)(type(self).list)'' – Prometheus

回答

2

下面是一類裝飾做它,因爲我想向你描述的註釋的一個例子。我在你的問題中填入了一些未定義的引用,並使用了一個超簡化版本的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 
相關問題