2010-01-01 242 views
25

decorator爲什麼不裝飾靜態方法或類方法?爲什麼@decorator不能裝飾靜態方法或類方法?

from decorator import decorator 

@decorator 
def print_function_name(function, *args): 
    print '%s was called.' % function.func_name 
    return function(*args) 

class My_class(object): 
    @print_function_name 
    @classmethod 
    def get_dir(cls): 
     return dir(cls) 

    @print_function_name 
    @staticmethod 
    def get_a(): 
     return 'a' 

兩個get_dirget_a結果AttributeError: <'classmethod' or 'staticmethod'>, object has no attribute '__name__'

爲什麼在屬性__name__而不是屬性func_name依賴decorator? (Afaik的所有功能,包括類方法和靜態方法,都具有func_name屬性。)

編輯:我正在使用Python 2.6。

+1

內部裝飾你爲什麼要調用函數(*參數)?它的工作就是簡單地返回一個函數(在你的情況下,未修改)。 – gahooa 2010-01-01 05:22:17

+4

gahooa:因爲這是「裝飾者」(他輸入的內容,而不是語言結構)的一種方式,請參閱http://pypi.python.org/pypi/decorator。 – 2010-01-01 06:28:24

+0

@taldor你有裝飾模塊在Python 2.6? – mykhal 2010-01-04 10:41:55

回答

22

它工作時@classmathod@staticmethod是最上面的裝飾:

from decorator import decorator 

@decorator 
def print_function_name(function, *args): 
    print '%s was called.' % function.func_name 
    return function(*args) 

class My_class(object): 
    @classmethod 
    @print_function_name 
    def get_dir(cls): 
     return dir(cls) 
    @staticmethod 
    @print_function_name 
    def get_a(): 
     return 'a' 
+7

作爲一項規則,'classmethod'和'staticmethod'應用一種特殊的魔法,並且必須被稱爲最後一個。 – 2010-01-01 17:33:21

3

這是你想要的嗎?

def print_function_name(function): 
    def wrapper(*args): 
     print('%s was called.' % function.__name__) 
     return function(*args) 
    return wrapper 

class My_class(object): 
    @classmethod 
    @print_function_name 
    def get_dir(cls): 
     return dir(cls) 

    @staticmethod 
    @print_function_name 
    def get_a(): 
     return 'a' 
+2

我不確定你是否意識到,但他使用的「裝飾器」包與「包裝器」的構造具有相同的功能。你的片段之間的唯一區別是在My_class中應用裝飾器的順序。您可以在答案中澄清說明爲什麼它解決了問題。 – 2010-01-01 12:04:42

+0

感謝您的更正。我正在玩py3k,裝飾模塊丟失的問題。我的意思是我的答覆是快速之一,肯定會有人張貼更好的答案有詳細的解釋 – mykhal 2010-01-01 15:20:55

+0

@(彼得·漢森)。然而,有在Python 2.6無裝飾模塊要麼 – mykhal 2010-01-04 10:41:19

37

classmethodstaticmethod回報descriptor objects,而不是功能。大多數裝飾器不是用來接受描述符的。

通常情況下,那麼,你必須申請classmethod和使用多個裝飾時staticmethod最後。並且由於裝飾者按「自下而上」的順序應用,因此通常應該在您的來源中最頂級的爲classmethodstaticmethod

像這樣:

class My_class(object): 
    @classmethod 
    @print_function_name 
    def get_dir(cls): 
     return dir(cls) 

    @staticmethod 
    @print_function_name 
    def get_a(): 
     return 'a' 
+7

+1實際回答問題(「爲什麼??」)。 – 2014-04-03 00:53:14

相關問題