1

我有兩個裝飾,定義如下,兩者都做同樣的事情:裝飾上既classmethods和實例方法的工作原理

# ONLY WORKS FOR CLASSMETHODS 
def paginated_class_method(default_page_size=25): 
    def wrap(func): 
     @functools.wraps(func) 
     def inner(cls, page=1, page_size=default_page_size, *args, **kwargs): 
      objects = func(cls=cls, *args, **kwargs) 
      return _paginate(objects, page, page_size) 
     return inner 
    return wrap 


# ONLY WORKS FOR INSTANCEMETHODS 
def paginated_instance_method(default_page_size=25): 
    def wrap(func): 
     @functools.wraps(func) 
     def inner(self, page=1, page_size=default_page_size, *args, **kwargs): 
      objects = func(self=self, *args, **kwargs) 
      return _paginate(objects, page, page_size) 
     return inner 
    return wrap 

我之所以有兩個是因爲類的方法,我需要傳遞第一個參數爲cls = cls,例如我需要傳遞self = self的方法。但這顯然不理想。有沒有人知道一種方法來構造一個可用於實例方法和類方法的裝飾器?

+0

你不需要'self'通過*或* 「cls」作爲關鍵字參數。如果這些是定位符,您可以使用任何本地名稱。 – 2013-02-28 15:39:55

+0

@MartijnPieters哦,我看到了問題;請注意'func'的第一個參數是一個關鍵字參數,可以是'self'或'cls'。這裏需要調整的實際情況是func的第一個參數沒有使用關鍵字參數。 – 2013-02-28 15:41:32

回答

3

只是通過在clsself作爲第一個位置參數,有無需通過他們作爲關鍵字參數:

def paginated_class_method(default_page_size=25): 
    def wrap(func): 
     @functools.wraps(func) 
     def inner(self_or_cls, page=1, page_size=default_page_size, *args, **kwargs): 
      objects = func(self_or_cls, *args, **kwargs) 
      return _paginate(objects, page, page_size) 
     return inner 
    return wrap 
+0

這是當我嘗試這種策略時,我失蹤的部分,我認爲:args = [self_or_cls] + args – 2013-02-28 15:42:16

+0

你繼續打我的評論更新2秒,從而使我的意見不相關。 ;) – 2013-02-28 15:44:06

+0

@ClayWardell:你可以傳入'self_or_cls'作爲第一個參數。 '* args'和** ** kwargs'不排除使用其他位置參數。 – 2013-02-28 15:44:15