通过将装饰器定义为类来装饰Python中的类

tsp*_*sps 18 python decorator

通过将装饰器定义为类来装饰类的简单示例是什么?

我正在尝试使用PEP 3129实现Python 2.6中实现的功能,除了使用类不是Bruce Eckel 在这里解释的类.

以下作品:

class Decorator(object):
    def __init__(self, arg):
        self.arg = arg

    def __call__(self, cls):
        def wrappedClass(*args):
            return cls(*args)
        return type("TestClass", (cls,), dict(newMethod=self.newMethod, classattr=self.arg))

    def newMethod(self, value):
        return value * 2

@Decorator("decorated class")
class TestClass(object):
    def __init__(self):
        self.name = "TestClass"
        print "init %s"%self.name

    def TestMethodInTestClass(self):
        print "test method in test class"

    def newMethod(self, value):
        return value * 3
Run Code Online (Sandbox Code Playgroud)

除了在上面,wrappedClass不是一个类,而是一个被操作来返回类类型的函数.我想写相同的可调用如下:

def __call__(self, cls):
        class wrappedClass(cls):
            def __init__(self):
                ... some code here ...
        return wrappedClass
Run Code Online (Sandbox Code Playgroud)

怎么做?

我不完全确定是什么进入""......这里的一些代码..."""

Sve*_*ach 18

如果要覆盖new_method(),只需执行以下操作:

class Decorator(object):
    def __init__(self, arg):
        self.arg = arg
    def __call__(self, cls):
        class Wrapped(cls):
            classattr = self.arg
            def new_method(self, value):
                return value * 2
        return Wrapped

@Decorator("decorated class")
class TestClass(object):
    def new_method(self, value):
        return value * 3
Run Code Online (Sandbox Code Playgroud)

如果您不想更改__init__(),则无需覆盖它.


Cri*_*cia 7

在此之后,类 NormalClass 成为 ClassWrapper实例

def decorator(decor_arg):

    class ClassWrapper:
        def __init__(self, cls):
            self.other_class = cls

        def __call__(self,*cls_ars):
            other = self.other_class(*cls_ars)
            other.field += decor_arg 
            return other

    return ClassWrapper

@decorator(" is now decorated.")
class NormalClass:
    def __init__(self, name):
        self.field = name

    def __repr__(self):
        return str(self.field)
Run Code Online (Sandbox Code Playgroud)

测试:

if __name__ == "__main__":

    A = NormalClass('A');
    B = NormalClass('B');

    print A
    print B
    print NormalClass.__class__
Run Code Online (Sandbox Code Playgroud)

输出:

A is now decorated. <br>
B is now decorated. <br>
\__main__.classWrapper
Run Code Online (Sandbox Code Playgroud)

  • 您忘记在 __call__ 方法中返回“其他”变量 (3认同)