2009-04-13 2 views
5

In python è possibile eseguire ciascuna funzione all'interno di una classe?Per ogni funzione della classe in python

EDIT: Quello che sto cercando di fare è chiamare le funzioni all'interno di una classe, raccogliere le loro variabili di ritorno e lavorare con quella.

risposta

3

Dipende cosa intendi per "funzione". Qualcosa di simile potrebbe funzionare, però:

import inspect 

def methods(c): 
    return (m for m in (getattr(c, d) for d in dir(c)) 
      if inspect.ismethoddescriptor(m) or inspect.ismethod(m)) 

Poi:

class C: 
    def f(self): pass 

>>> list(methods(C)) 
[<unbound method C.f>] 
+0

-1 Per bloccare l'intera espressione nell'istruzione return rendendola completamente illeggibile. –

4

sì, è possibile. veloce e sporco:

class foo: 
    def one(self): 
     print "here is one" 
    def two(self): 
     print "here is two" 
    def three(self): 
     print "here is three" 


obj = foo() 
for entry in dir(obj): 
    print entry, callable(getattr(obj,entry)) 
    if callable(getattr(obj,entry)): 
     getattr(obj,entry)() 

Se si desidera un concetto più raffinato, controllare il modulo unittest.py. Ci dovrebbe essere il codice che esegue tutti i metodi che iniziano con la stringa "test"

1

Ecco uno che usa il rendimento per scorrere le funzioni nella classe.

def get_functions(mod): 
    for entry in dir(mod): 
     obj=getattr(mod,entry); 
     if hasattr(obj, '__call__') and hasattr(obj,'__func__') : 
      yield obj 

class foo: 
    def one(self): 
     print ("here is two") 
     return 1 
    def two(self): 
     print ("here is two") 
     return 2 
    def three(self): 
     print ("here is three") 
     return 3 


print(sum([fun() for fun in get_functions(foo())])) 
1

Dal momento che hai scritto la classe, che già conosce tutte le funzioni.

class ThisIsPeculiar(object): 
    def aFunction(self, arg1): 
     pass 
    def anotherFunction(self, thisArg, thatArg): 
     pass 
    functionsToCall = [ aFunction, anotherFunction ] 

>>> p= ThisIsPeculiar() 
>>> p.functionsToCall 
[<function aFunction at 0x6b830>, <function anotherFunction at 0x6b870>] 
+0

Sì, ma questo viola il principio Do not Repeat Yourself. Inoltre, potrebbe non possedere il codice che desidera esercitare o non voler aggiungere inutili turds. –

+0

Non sembra violare DRY per me. Puoi facilmente avere metodi che non vuoi chiamare automaticamente. Questo identifica positivamente la lista dei metodi che vengono chiamati. –

1

Provare a utilizzare il inspect module:

import inspect 

class Spam: 
    def eggs(self): 
     print "eggs" 
    def ducks(self): 
     print "ducks" 
    value = "value" 

spam = Spam() 
for name, method in inspect.getmembers(spam, callable): 
    method() 

uscita:

ducks 
eggs 
3

Il dir builtin elencherà tutti gli attributi di un oggetto, ad esempio:

>>> class MyClass: 
...  def one(self): 
...   print "one" 
...  def two(self): 
...   print "two" 
...  def three(self): 
...   print "three" 
... 
>>> dir(MyClass) 
['__doc__', '__module__', 'one', 'three', 'two'] 

I t funziona anche su una classe inizializzato ..

>>> c = MyClass() 
>>> dir(c) 
['__doc__', '__module__', 'one', 'three', 'two'] 

metodi sono solo gli attributi che capita di essere callable (via c.attribute()) - siamo in grado di utilizzare la funzione di getattr fare riferimento a quel metodo tramite una variabile ..

>>> myfunc = getattr(c, 'one') 
>>> myfunc 
<bound method MyClass.one of <__main__.MyClass instance at 0x7b0d0>> 

Allora possiamo semplicemente chiamiamo variabile ..

>>> myfunc() 
one # the output from the c.one() method 

Dal momento che alcuni attributi non sono funzioni (nell'esempio di cui sopra, __doc__ e __module__). Noi siamo in grado il callable builtin per verificare se si tratta di un metodo callable (una funzione):

>>> callable(c.three) 
True 
>>> callable(c.__doc__) 
False 

Quindi, per combinare tutto ciò che in un ciclo:

>>> for cur_method_name in dir(c): 
...  the_attr = getattr(c, cur_method_name) 
...  if callable(the_attr): 
...    the_attr() 
... 
one 
three 
two 

Ricordate questo chiamerà metodi come __init__ ancora una volta, che probabilmente non è desiderato.È possibile saltare qualsiasi cur_method_name che inizia con un carattere di sottolineatura