首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何对类方法进行类修饰

如何对类方法进行类修饰
EN

Stack Overflow用户
提问于 2019-06-25 05:40:02
回答 1查看 50关注 0票数 0

我为继承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()时,它给出了上面的错误。

代码语言:javascript
复制
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()

期望值:

代码语言:javascript
复制
"hello"
"testing"
"hello"
"testing"

Actual: TypeError: unbound method wrapper() must be called with TestClass instance as first argument (got nothing instead)
EN

回答 1

Stack Overflow用户

发布于 2019-06-25 06:03:18

您的程序有一些问题;我不会详细介绍所有细节,而是指出获得所需输出的方法。

之所以引发该错误,是因为您已经覆盖了TestClass中的类方法what,该类方法现在接受cna为anything的单个参数cls。换句话说,您还需要使用classmethod装饰器来装饰子类中的类方法。

如果你想保留你当前的代码,你需要提供cls参数,如下所示:

代码语言:javascript
复制
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__属性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56744277

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档