2009-04-13 8 views
5

En python est-il possible d'exécuter chaque fonction dans une classe? Ce que j'essaie de faire est d'appeler les fonctions à l'intérieur d'une classe, collecter leurs variables de retour et de travailler avec cela.Pour chaque fonction en classe dans python

Répondre

3

Cela dépend de ce que vous entendez par "fonction". Quelque chose comme cela pourrait fonctionner, si:

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

Puis:

class C: 
    def f(self): pass 

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

-1 Pour coller l'expression entière dans l'instruction return qui la rend totalement illisible. –

4

oui, vous pouvez. rapide et sale:

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

Si vous voulez un concept plus raffiné, vérifiez le module unittest.py. Il devrait y avoir un code qui exécute toutes les méthodes en commençant par la chaîne "test"

1

Voici un qui utilise le rendement en boucle à travers les fonctions de la 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

Depuis que vous avez écrit la classe, vous avez déjà connaissez toutes les fonctions.

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

Oui, mais cela viole le principe Ne vous répétez pas. En outre, il peut ne pas posséder le code qu'il veut exercer, ou ne pas vouloir ajouter des turds inutiles. –

+0

ne semble pas violer DRY pour moi. Vous pouvez facilement avoir des méthodes que vous ne voulez pas appelées automagiquement. Ceci identifie positivement la liste des méthodes qui sont appelées. –

1

Essayez d'utiliser le 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() 

Sortie:

ducks 
eggs 
3

Le dir builtin répertorie tous les attributs d'un objet, par exemple:

>>> 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 travaille également sur une classe initialisés ..

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

Les méthodes sont les attributs juste qui se trouvent être appelable (via c.attribute()) - nous pouvons utiliser la fonction getattr pour faire référence à cette méthode par une variable ..

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

Ensuite, nous pouvons simplement appeler cette variable ..

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

Étant donné que certains attributs ne sont pas des fonctions (dans l'exemple ci-dessus, __doc__ et __module__). Nous pouvons nous le callable builtin pour vérifier si elle est une méthode appelable (fonction):

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

donc de combiner tout cela dans une boucle:

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

Rappelez-vous ceci appellera des méthodes telles que __init__ à nouveau, qui n'est probablement pas désiré.Vous pouvez ignorer tout cur_method_name qui commence par un trait de soulignement

Questions connexes