2012-03-28 101 views
14

有人可以展示一个简单的例子吗?我想达到什么在Python 2.6使用PEP 3129已经实现,但使用的类不作为布鲁斯·埃克尔解释herepython:通过将装饰器定义为类来装饰一个类

以下工作:

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 

除,在上面,wrappedClass不是类但被操作来返回类类型的函数。我想写出相同的可调用方式如下:

def __call__(self, cls): 
     class wrappedClass(cls): 
      def __init__(self): 
       ... some code here ... 
     return wrappedClass 

这将如何完成? 编辑:我不完全知道什么进入“”“......一些代码在这里......‘’”

+0

您是否试过自己发布的代码?它应该工作。 – 2012-03-28 11:04:31

+0

使用该功能的第一部分确实起作用。我怎么会把wrappedClass写成真正的类呢? – tsps 2012-03-28 11:08:26

+1

你的装饰者应该做什么?我不能告诉你什么代码必须进入“一些代码”,而不知道代码应该做什么。 – 2012-03-28 12:41:58

回答

13

如果你想覆盖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 

如果你不想改变__init__(),你不需要覆盖它。

2

在此之后,类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 ClassWrapper 

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

    def __repr__(self): 
     return str(self.field) 

测试:

if __name__ == "__main__": 

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

    print A 
    print B 
    print NormalClass.__class__ 

输出:

一个装饰了。
B现在装饰。
__main __。classWrapper

+2

你忘记了在__call__方法中返回'other'变量 – 2014-11-09 09:26:08