在Python中装饰方法签名中没有self的类

时间:2016-01-18 11:02:51

标签: python metaprogramming python-decorators

我正在尝试动态地将decorator应用于类。 如果我有一个包含self in method signature的类方法,它就可以工作。

工作示例:

from functools import wraps

def debug(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print('awesome')
        f = func(*args, **kwargs)
        return f
    return wrapper

def debugclass(cls):
    # cls is a class
    for key, val in vars(cls).items():
        if callable(val):
            setattr(cls, key, debug(val))
    return cls

class Dude:
    def test(self):
    #def test(): # this does not work
        pass

debugclass(Dude)
dude = Dude()
dude.test()

我如何更改Dude类方法签名,以便在没有自己成为签名一部分的情况下工作?

class Dude:
    def test(): # without self
        pass
debugclass(Dude)
dude = Dude()
dude.test()

获取错误:

Traceback (most recent call last):
File "withoutself.py", line 33, in <module>
dude.test()
File "withoutself.py", line 7, in wrapper
f = func(*args, **kwargs)
TypeError: test() takes no arguments (1 given)

2 个答案:

答案 0 :(得分:3)

要使test()方法在没有selfcls参数的情况下可以调用,您需要将其设为staticmethod

class Dude:
    @staticmethod
    def test():
        pass

然后,您还需要更新debugclass以包装staticmethod个对象,因为它们不是callables。不幸的是,你需要一种不同的方法来包装staticmethod对象:

def debugclass(cls):
    # cls is a class
    for key, val in vars(cls).items():
        if callable(val):
            setattr(cls, key, debug(val))
        elif isinstance(val, staticmethod):
            setattr(cls, key, staticmethod(debug(val.__func__)))
    return cls

>>> class Dude:
    def test(self):
        pass
    @staticmethod
    def test1():
        pass


>>> debugclass(Dude)
<class __main__.Dude at 0x7ff731842f58>
>>> Dude().test()
awesome
>>> Dude.test1()
awesome

答案 1 :(得分:0)

很快,你不能。 Elaboratedely,python在调用方法时将对象实例作为第一个参数传递。因此,如果您定义一个没有参数的方法,您将获得该execption。给出的1个参数是你的“dude”对象。

有关详细信息,请参阅https://docs.python.org/2/tutorial/classes.html#method-objects