2014-09-25 27 views
5

Dire che ho una classe con un sacco di metodi:Python: fai qualcosa per qualsiasi metodo di una classe?

class Human(): 

    def eat(): 
    print("eating") 

    def sleep(): 
    print("sleeping") 

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

Poi corro tutti i metodi con

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

voglio correre print("I am") per ogni metodo chiamato. Quindi dovrei ottenere qualcosa come

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

C'è un modo per farlo senza dover riformattare ogni metodo?

+7

Utilizzare un decoratore, applicandolo a tutti metodi: [Allegare un decoratore a tutte le funzioni all'interno di una classe] (http://stackoverflow.com/q/3467526) e [Scrivere un decoratore di classe che applica un decoratore a tutti i metodi] (http://stackoverflow.com/q/6695854) –

+0

Se si sta tentando di ridurre al minimo il numero di modifiche che è necessario apportare, la cosa più semplice da fare è semplicemente modificare la definizione di ciascun metodo. Se stai cercando un modo per isolare la modifica in un singolo luogo, per essere applicabile a qualsiasi metodo attuale o futuro, i decoratori sono la strada da percorrere. – chepner

+0

Perché non avere una funzione 'def do (self, action)', quindi 'eat' diventa semplicemente self.do (" eating ")' e qualsiasi altra modifica all'output avviene in un posto. – jonrsharpe

risposta

5

Se non è possibile cambiare il modo di chiamare i metodi è possibile utilizzare il metodo magico __getattribute__ voi (i metodi sono attributi anche ricordare!) solo essere attenti a controllare il tipo di attributi in modo da non stampare "io sono:" ogni volta che si desidera accedere a qualsiasi puntura o int attributi si può avere:

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

Uscite:

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

È possibile scrivere un altro metodo come def iam() e scrivere il codice nel metodo print "i am \n" e chiamare prima di ogni metodo.

2

Puoi farlo se non ti dispiace aggiungere un metodo __init__ e __call__ alla tua classe e self agli argomenti del tuo metodo.

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: vedere la mia altra risposta per una soluzione migliore

+0

Grazie, ma questa soluzione cambia la sintassi di come chiamo i metodi .. – Pithikos

+0

@Pithikos vedi la mia altra risposta per una soluzione che non richiede di cambiare il modo in cui chiami i tuoi metodi – nettux443

Problemi correlati