Python装饰器作为一种静态方法

我想写一个python类,它使用需要实例状态信息的装饰器函数。 这是按预期工作,但如果我明确地使装饰器staticmetod,我得到以下错误:

Traceback (most recent call last): File "tford.py", line 1, in <module> class TFord(object): File "tford.py", line 14, in TFord @ensure_black TypeError: 'staticmethod' object is not callable 

为什么?

这里是代码:

 class TFord(object): def __init__(self, color): self.color = color @staticmethod def ensure_black(func): def _aux(self, *args, **kwargs): if self.color == 'black': return func(*args, **kwargs) else: return None return _aux @ensure_black def get(): return 'Here is your shiny new T-Ford' if __name__ == '__main__': ford_red = TFord('red') ford_black = TFord('black') print ford_red.get() print ford_black.get() 

如果我只是删除行@staticmethod ,一切正常,但我不明白为什么。 它不是需要self作为第一个参数?

这不是staticmethod方法应该如何使用。 staticmethod对象是返回被包装对象的描述符 ,所以它们只在作为classname.staticmethodname访问时才起作用。 例

 class A(object): @staticmethod def f(): pass print Af print A.__dict__["f"] 

版画

 <function f at 0x8af45dc> <staticmethod object at 0x8aa6a94> 

A的范围内,你总是会得到后一个不可调用的对象。

我强烈build议将dcorator移动到模块范围 – 它似乎不属于课堂内部。 如果你想把它放在课堂上,不要把它作为一个staticmethod ,而只是简单del把它放在课程结束的时候 – 在这种情况下,并不意味着要在课堂外使用它。

在评估类声明的内容之后,Python类将在运行时创build。 通过将所有声明的variables和函数赋值给一个特殊的字典并使用该字典来调用type.__new__ (请参阅定制类创build )来type.__new__ 该类 。

所以,

 class A(B): c = 1 

相当于:

 A = type.__new__("A", (B,), {"c": 1}) 

当你使用@staticmethod注解一个方法时,在type.__new__的类中创build了一些特殊的魔法。 在类声明范围内,@staticmethod函数只是静态方法对象的一个​​实例,您不能调用它。 装饰器可能应该在相同模块中的类定义之上或者在单独的“装饰”模块(取决于你有多less装饰器)中声明。 一般来说,装饰器应该在一个类之外声明。 一个值得注意的例外是属性类(参见属性 )。 在你的情况下,如果你有一个类的颜色,类装饰器里面的装饰器可能是有意义的:

 class Color(object): def ___init__(self, color): self.color = color def ensure_same_color(f): ... black = Color("black") class TFord(object): def __init__(self, color): self.color = color @black.ensure_same_color def get(): return 'Here is your shiny new T-Ford' 

ensure_black正在返回未由@staticmethod装饰的@staticmethod

您可以将一个非静态方法返回给static_method

http://docs.python.org/library/functions.html#staticmethod