繁体   English   中英

如何类装饰一个类方法

[英]How to class decorate a class method

我正在使用类装饰器来继承SuperClass的子类TestClass。 我在SuperClass中有一个类方法叫做什么(cls),它接受一个类。 我希望能够在我的子类TestClass中装饰该类,但它并没有让我这么说。

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

我试图对我的TestClass对象进行实例化,然后使用它来调用方法testclass.what(cls)并且这样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)

您的计划存在一些问题; 而不是去了解所有细节,我会指出获得所需输出的方法。

被引发的错误,因为你已经重写了类方法whatTestClass ,现在只有一个参数cls是CNA是任何东西。 换句话说,您还需要使用classmethod装饰器来装饰子类中的classmethod

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

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在基础上进行递归(这里你不需要)。 此外,不是检查__call__属性,而是使用callable

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM