2012-03-28 20 views
14

¿Podría alguien mostrar un ejemplo simple de esto? Estoy tratando de lograr lo que se ha implementado en Python 2.6 utilizando PEP 3129, excepto el uso de clases no funciona como Bruce Eckel explica herepython: decorar una clase definiendo el decorador como una clase

las siguientes obras:

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 

Excepto en lo anterior, no es un wrappedClass clase pero una función manipulada para devolver un tipo de clase. Me gustaría escribir el mismo invocable de la siguiente manera:

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

¿Cómo se haría esto? EDITAR: No estoy del todo seguro de lo que pasa en "" "... algún código aquí ... ''"

+0

¿Has probado el código que publicaste? Deberia de funcionar. –

+0

La primera parte que usa la función funciona. Sin embargo, ¿cómo iba a escribir wrappedClass como una clase genuina? – tsps

+1

¿Qué debe hacer su decorador? No puedo decirte qué código tiene que entrar en "algún código aquí" sin saber lo que se supone que debe hacer este código. –

Respuesta

13

Si desea sobrescribir new_method(), simplemente lo hacemos:

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 

Si no desea modificar __init__(), no necesita sobrescribirlo.

2

Después de esto, el NormalClass clase se convierte en un ClassWrapper ejemplo:

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) 

prueba:

if __name__ == "__main__": 

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

    print A 
    print B 
    print NormalClass.__class__ 

Salida:

A está decorado.
B ahora está decorado.
__main __. ClassWrapper

+2

se le olvidó devolver la 'otra' variable dentro del método __call__ –

Cuestiones relacionadas