2010-06-08 22 views
6

Quiero hacer que mi clase de Python se comporte de tal manera que cuando se llama a cualquier método de clase se ejecuta primero un método predeterminado sin especificarlo explícitamente en la clase llamada. Un ejemplo puede ayudar :)¿Cómo hacer que cada método de clase llame a un método específico antes de la ejecución?

Class animals: 
    def _internalMethod(): 
     self.respires = True 

    def cat(): 
     self._internalMethod() 
     self.name = 'cat' 

    def dog(): 
     self._internalMethod() 
     self.name = 'dog' 

Quiero _internalMethod() que se llamará automáticamente cuando cualquier método es llamado desde una instancia de animales, en vez de indicar explícitamente en el def de cada método. ¿Hay una manera elegante de hacer esto?

Saludos,

Respuesta

5

Se puede usar un metaclase y getattribute para decorar todos los métodos dinámicamente (si está utilizando Python 2, asegúrese de subclase de object!).

Otra opción es sólo para tener una corrección en la clase, como:

def add_method_call(func, method_name): 
    def replacement(self, *args, **kw): 
     getattr(self, method_name)() 
     return func(self, *args, **kw) 
    return replacement 

def change_all_attrs(cls, added_method): 
    for method_name in dir(cls): 
     attr = getattr(cls, method_name) 
     if callable(attr): 
      setattr(cls, method_name, add_method_call(attr, added_method)) 

class animals(object): 
    ... 

change_all_attrs(animals, '_internalMethod') 

Esto es un poco descuidado, dir() no recibirá los métodos de las superclases, y es posible coger propiedades y otros objetos le no lo intenté debido a la simple prueba callable(attr). Pero podría funcionar bien para ti.

Si usa Python 2.7+ puede usar un decorador de clases en lugar de llamar a change_all_attrs después de crear la clase, pero el efecto es el mismo (excepto que tendrá que volver a escribir change_all_attrs para hacerlo decorador).

Cuestiones relacionadas