在 Python 中装饰方法签名中没有 self 的类
Posted
技术标签:
【中文标题】在 Python 中装饰方法签名中没有 self 的类【英文标题】:Decorate class that has no self in method signature in Python 【发布时间】:2016-04-23 12:42:00 【问题描述】:我正在尝试将装饰器动态应用于类。 如果我有一个在方法签名中包含 self 的类方法,它就可以工作。
工作示例:
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 类方法签名,使其在 self 不参与签名的情况下也能正常工作?
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)
【问题讨论】:
【参考方案1】:要使您的 test()
方法在没有 self
或 cls
参数的情况下可调用,您需要将其设为 staticmethod
。
class Dude:
@staticmethod
def test():
pass
然后您还需要更新 debugclass
以包装 staticmethod
对象,因为它们不是可调用对象。不幸的是,您需要一种不同的方式来包装 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
【讨论】:
谢谢!解释得很好。【参考方案2】:很快,你不能。 详细地说,python 在调用方法时将对象实例作为第一个参数传递。因此,如果您定义一个没有参数的方法,您将获得执行。给定的 1 个参数是您的“老兄”对象。
更多信息请查看https://docs.python.org/2/tutorial/classes.html#method-objects
【讨论】:
以上是关于在 Python 中装饰方法签名中没有 self 的类的主要内容,如果未能解决你的问题,请参考以下文章
Python3-2020-测试开发-20- Python中装饰器@property