2014-09-25 7 views
5

sagen, dass ich eine Klasse mit einer Reihe von Methoden haben:Python: Etwas für jede Methode einer Klasse tun?

class Human(): 

    def eat(): 
    print("eating") 

    def sleep(): 
    print("sleeping") 

    def throne(): 
    print("on the throne") 

Dann

alle Methoden mit Ich betreibe
John=Human() 
John.eat() 
John.sleep() 
John.throne() 

Ich möchte print("I am") für jede Methode wird aufgerufen laufen. Also sollte ich etwas wie

I am: 
eating 
I am: 
sleeping 
I am: 
on the throne 

bekommen Gibt es eine Möglichkeit, dies zu tun, ohne jede Methode neu formatieren müssen?

+7

einen Dekorateur verwenden, ist es für alle Anwendung Methoden: [Einen Decorator an alle Funktionen innerhalb einer Klasse anhängen] (http://stackoverflow.com/q/3467526) und [Einen Klassendekorator schreiben, der einen Decorator auf alle Methoden anwendet] (http://stackoverflow.com/q/6695854) –

+0

Wenn Sie versuchen, die Anzahl der zu bearbeitenden Änderungen zu minimieren, ist es am einfachsten, die Definition der einzelnen Methoden zu ändern. Wenn Sie nach einer Möglichkeit suchen, die Änderung an einem einzigen Ort zu isolieren, um auf eine aktuelle oder zukünftige Methode anwendbar zu sein, sind Dekorateure der richtige Weg. – chepner

+0

Warum nicht eine Funktion 'def do (self, action)' haben, dann wird 'essen' einfach zu' self.do ("essen") und weitere Änderungen an der Ausgabe passieren an einer Stelle. – jonrsharpe

Antwort

5

Wenn Sie nicht ändern können, wie Sie Ihre Methoden rufen Sie die __getattribute__ magische Methode verwenden, können Sie (Methoden Attribute erinnern werden!) muss nur vorsichtig sein, die Art der Attribute zu überprüfen, so dass Sie nicht drucken „ich bin“ jedes Mal, wenn jeder Stachel zugreifen möchten oder int-Attribute Sie haben können:

import types 

class Human(object): 
    def __getattribute__(self, attr): 
     method = object.__getattribute__(self, attr) 
     if not method: 
      raise Exception("Method %s not implemented" % attr) 
     if type(method) == types.MethodType: 
      print "I am:" 
     return method 

    def eat(self): 
     print "eating" 

    def sleep(self): 
     print "sleeping" 

    def throne(self): 
     print "on the throne" 

John = Human() 
John.eat() 
John.sleep() 
John.throne() 

Ausgänge:

I am: 
eating 
I am: 
sleeping 
I am: 
on the throne 
-3

Sie können eine andere Methode wie def iam() schreiben und Code in Methode print "i am \n" schreiben und vor jeder Methode aufrufen.

2

Sie können dies tun, wenn es Ihnen nichts ausmacht eine __init__ und __call__ Methode zu Ihrer Klasse und self zu den Argumenten Ihrer Methode hinzuzufügen.

class Human(): 
    def __init__(self): 
     return None 
    def __call__(self, act): 
     print "I am:" 
     method = getattr(self, act) 
     if not method: 
      raise Exception("Method %s not implemented" % method_name) 
     method() 

    def eat(self): 
     print "eating" 

    def sleep(self): 
     print "sleeping" 

    def throne(self): 
     print "on the throne" 

John = Human() 
John("eat") 
John("sleep") 
John("throne") 

EDIT: siehe meine andere Antwort für eine bessere Lösung

+0

Danke, aber diese Lösung ändert die Syntax, wie ich die Methoden aufrufen. – Pithikos

+0

@Pithikos siehe meine andere Antwort für eine Lösung, die nicht erfordert, dass Sie die Art ändern, wie Sie Ihre Methoden aufrufen – nettux443

Verwandte Themen