如何为类定义装饰器以装饰类方法

时间:2019-10-05 04:36:19

标签: python python-3.x

我想在类方法中添加一些固定的变量。但是我不想每次使用它们时都传递这些变量。我不能直接修饰类方法,因为我的类是子类,并且不能修改父类。 这是我想尝试的:

def callable(o):
    return hasattr(o, "__call__")

def trace(f):
    def traced(*args, **kw):
        "Print message before and after a function call."
        print("Entering", f.__name__)
        kw['new value'] = 'new value'
        result = f(*args, **kw)
        print("Leaving", f.__name__)
        return result
    return traced

def mtrace(cls):
    for key, val in cls.__dict__.items():
        if key.startswith("__") and key.endswith("__") or not callable(val):
            continue
        print('calling in mtrace', key)
        setattr(cls, key, trace(val))
        print("Wrapped", key)
    return cls


class dull:

    @classmethod
    def method1(cls, **arg):
        print("Method 1 called with arg", arg)

@mtrace
class myclass(dull):pass


myclass.method1(a='hello')

输出为:

try class method
Method 1 called with arg {'a': 'hello'}

新值未添加到method1中。我不太了解python解释器如何调用类方法。非常感谢任何人能帮助我。

1 个答案:

答案 0 :(得分:0)

我尝试使用super重新定义父类。它按我的意愿工作。但是我没有使用装饰器。但这看起来并不漂亮。

class BaseRequest:  # cannot modify this class

    @classmethod
    def http_get(cls, *vars, **kws):
        print("Method 1 called with arg", kws)

class MyRequest(BaseRequest):
    extra_vars = {}

    @classmethod
    def http_get(cls, *vars, **kws):
        kws.update(cls.extra_vars)
        super().http_get(*vars, **kws)

    @classmethod
    def set_extra_vars(cls, **kws):
        cls.extra_vars.update(kws)

MyRequest.set_extra_vars(header='my hearders')
MyRequest.http_get(a='hello')

输出 用arg {'a':'hello','header':'my听众'}调用方法1