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