Python装饰器作为静态方法 [英] Python decorator as a staticmethod

查看:92
本文介绍了Python装饰器作为静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个使用装饰器函数的python类,该装饰器函数需要实例状态的信息。这可以按预期工作,但是如果我将装饰器明确地设为staticmetod,则会出现以下错误:

I'm trying to write a python class which uses a decorator function that needs information of the instance state. This is working as intended, but if I explicitly make the decorator a staticmetod, I get the following error:

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 ,everythin g有效,但我不明白为什么。

And if I just remove the line @staticmethod, everything works, but I do not understand why. Shouldn't it need self as a first argument?

推荐答案

这不是它的第一参数吗?

This is not how staticmethod is supposed to be used. staticmethod objects are descriptors that return the wrapped object, so they only work when accessed as classname.staticmethodname. Example

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

打印

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

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

Inside the scope of A, you would always get the latter object, which is not callable.

我强烈建议将装饰器移至模块作用域-它似乎不属于类内部。如果要将其保留在类中,请不要使其成为静态方法,而只需在 del 类主体的末尾-在这种情况下,不能在类外使用。

I'd strongly recommend to move the decorator to the module scope -- it does not seem to belong inside the class. If you want to keep it inside the class, don't make it a staticmethod, but rather simply del it at the end of the class body -- it's not meant to be used from outside the class in this case.

这篇关于Python装饰器作为静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆