我为继承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)
发布于 2019-06-25 06:03:18
您的程序有一些问题;我不会详细介绍所有细节,而是指出获得所需输出的方法。
之所以引发该错误,是因为您已经覆盖了TestClass
中的类方法what
,该类方法现在接受cna为anything的单个参数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__
,因为dir
在基数上进行递归(这里不需要)。此外,使用callable
而不是检查__call__
属性。
https://stackoverflow.com/questions/56744277
复制相似问题