2010-06-08 3 views
6

Ich möchte, dass meine Python-Klasse sich so verhält, dass beim Aufruf einer Klassenmethode zuerst eine Standardmethode ausgeführt wird, ohne diese explizit in der aufgerufenen Klasse anzugeben. Ein Beispiel kann helfen :)Wie kann jede Klassenmethode vor der Ausführung eine bestimmte Methode aufrufen?

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

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

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

Ich möchte _internalMethod() automatisch aufgerufen wird, wenn ein beliebiges Verfahren aus einer Instanz von Tieren genannt wird, anstatt sie explizit in der def jeder Methode besagt. Gibt es eine elegante Möglichkeit, dies zu tun?

Cheers,

Antwort

5

Sie eine Metaklasse und getattribute alle Methoden dekorieren dynamisch nutzen könnten (wenn Sie Python 2 verwenden, sollten Sie von object Unterklasse!).

Eine weitere Option nur eine Korrektur auf der Klasse haben, wie:

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') 

Dies ist eine Art von schlampig, dir() werden keine Methoden in Super, und Sie können Sie Eigenschaften und andere Objekte fangen wegen des einfachen callable(attr) Tests nicht beabsichtigen. Aber es könnte für Sie gut funktionieren.

Wenn Sie Python 2.7+ verwenden, können Sie nach dem Erstellen der Klasse einen Klassendekorator anstelle des Aufrufs change_all_attrs verwenden, aber der Effekt ist derselbe (außer Sie müssen change_all_attrs umschreiben, um es zu einem Dekorator zu machen).

Verwandte Themen