2010-01-01 79 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

相关问题