views:

439

answers:

6

In python is it possible to run each function inside a class?

EDIT: What i am trying to do is call of the functions inside a class, collect their return variables and work with that.

+2  A: 

yes, you can. Quick and dirty:

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

If you want a more refined concept, check the unittest.py module. There should be code that executes all methods starting with the string "test"

Stefano Borini
+4  A: 

Depends what you mean by "function". Something like this could work, though:

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

Then:

class C:
    def f(self): pass

>>> list(methods(C))
[<unbound method C.f>]
Nicholas Riley
+1  A: 

Here is one that uses yield to loop through the functions in the class.

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())]))
Rex Logan
+1  A: 

Since you wrote the class, you already know all the functions.

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>]
S.Lott
Yeah, but that violates the Don't Repeat Yourself principle. Besides, he may not own the code that he wants to exercise, or not want to add unnecessary turds.
George V. Reilly
Doesn't seem to violate DRY to me. You can easily have methods you don't want called automagically. This positively identifies the list of methods which are called.
S.Lott
+1  A: 

Try using the 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()

Output:

ducks
eggs
Ryan Ginstrom
+1  A: 

The dir builtin will list all attributes of an object, for example:

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

It also works on an initialised class..

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

Methods are just attributes which happen to be callable (via c.attribute() ) - we can use the getattr function to reference that method via a variable..

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

Then we can simply call that variable..

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

Since some attributes are not functions (in the above example, __doc__ and __module__). We can us the callable builtin to check if it's a callable method (a function):

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

So to combine all that into a loop:

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

Remember this will call methods like __init__ again, which probably isn't desired. You might want to skip any cur_method_name which start with an underscore

dbr