python - 如何类装饰类方法
问题描述
我正在为继承 SuperClass 的子类 TestClass 使用类装饰器。我在 SuperClass 中有一个名为 what(cls) 的类方法,它接受一个类。我希望能够在我的子类 TestClass 中装饰该类,但它并没有像它所说的那样让我这样做。
TypeError: unbound method wrapper() must be called with TestClass instance as first argument (got nothing instead)
我试图对我的 TestClass 对象进行实例化,然后使用它来调用方法testclass.what(cls)
并且它有效,但是当我这样做时TestClass.what()
,它给了我上面的错误。
def class_decorator(cls):
for attr_name in dir(cls):
attr_value = getattr(cls, attr_name)
if hasattr(attr_value, '__call__'): # check if attr is a function
# apply the function_decorator to your function
# and replace the original one with your new one
setattr(cls, attr_name, ball(attr_value))
return cls
def ball(func):
def wrapper(*args, **kwargs):
print("hello")
return func(*args, **kwargs)
return wrapper
class SuperClass:
def __init__(self):
pass
@classmethod
def what(cls):
print("testing")
@class_decorator
class TestClass(SuperClass):
def what(cls):
super().what()
TestClass.what()
预期的:
"hello"
"testing"
"hello"
"testing"
Actual: TypeError: unbound method wrapper() must be called with TestClass instance as first argument (got nothing instead)
解决方案
您的程序存在一些问题;我将指出获得所需输出的方法,而不是详细介绍所有细节。
之所以会引发错误,是因为您已经覆盖了 中的类方法what
,TestClass
它现在接受一个cls
可以是任何东西的参数。换句话说,您还需要使用classmethod
装饰器在子类中装饰您的类方法。
如果要保留当前代码,则需要显式提供cls
参数,如下所示:
from functools import partial
def class_decorator(cls):
for attr_name in vars(cls):
attr_value = getattr(cls, attr_name)
if callable(attr_value): # check if attr is a function
if attr_name == 'what':
setattr(cls, attr_name, partial(ball(attr_value), cls=cls))
else:
setattr(cls, attr_name, ball(attr_value))
使用partial
将类作为第一个参数传递。
另外,我曾经在基础上vars(cls)
获得cls.__dict__
as dir
does 递归(您不希望在这里)。此外,不要检查__call__
属性,而是使用callable
.
推荐阅读
- doxygen - 如何在 doxygen 中创建 switch case 语句列表?
- mysql - 续集嵌套模型
- excel - PowerShell:如何将表格添加到 Excel 电子表格
- api - 如何在不使用空手道重复相同功能的测试的情况下为不同的基本 url 运行具有动态表的场景
- macos - VSCode 集成终端中的 $PATH 不一致
- scala - 在 Scala 中清除控制台
- kubernetes - 如何为应用程序 dotnetcore 编写 configmap
- accessibility - 为什么在使用屏幕阅读器浏览页眉时,总是会读取上方的页眉按钮?
- java - 如何将 JSON 字符串反序列化为枚举
- angular - 以角度一次上传一个文件