Is there a way to execute a loop and execute all the functions in a Python class?

I have

class Foo(): function bar(): pass function foobar(): pass 

Instead of executing each function in order:

 x = Foo() x.bar() x.foobar() 

Is there a built-in way to loop through and execute each function in the sequence in which they are written in the class?

+6
python reflection class
source share
5 answers

Not. You can access Foo.__dict__ and call each value in turn (catch errors for non-invocable members), but the order is not preserved.

 for callable in Foo.__dict__.values(): try: callable() except TypeError: pass 

This assumes that none of the functions accept parameters, as in your example.

+6
source share
 def assignOrder(order): @decorator def do_assignment(to_func): to_func.order = order return to_func return do_assignment class Foo(): @assignOrder(1) def bar(self): print "bar" @assignOrder(2) def foo(self): print "foo" #don't decorate functions you don't want called def __init__(self): #don't call this one either! self.egg = 2 x = Foo() functions = sorted( #get a list of fields that have the order set [ getattr(x, field) for field in dir(x) if hasattr(getattr(x, field), "order") ], #sort them by their order key = (lambda field: field.order) ) for func in functions: func() 

This funny @assignOrder(1) above def bar(self) launches this:

 Foo.bar = assignOrder(1)(Foo.bar) 

assignOrder(1) returns a function that takes another function, changes it (adds the order field and sets it to 1 ), and returns it. Then this function is called by the function that it decorates (thus, its order field is set); the result replaces the original function.

This is a more convenient, more readable, and more convenient way to say:

  def bar(self): print "bar" Foo.bar.order = 1 
+8
source share

Since Python stores the methods (and other attributes) of a class in a dictionary that is fundamentally disordered, this is not possible.

If you don't need order, use the __dict__ class:

 x = Foo() results = [] for name, method in Foo.__dict__.iteritems(): if callable(method): results.append(method(x)) 

This also works if the function accepts additional parameters - just put them after the class instance.

+5
source share

While you're only interested in Python 3.x (and from the empty parentheses in your class statement, I think you might be), then there really is an easy way to do this without decorators: Python 3 allows you to provide your own dictionary, for example, object to be used during class definition.

The following code is from PEP3115, with the exception of the last two lines, which I added to print the methods in order:

 # The custom dictionary class member_table(dict): def __init__(self): self.member_names = [] def __setitem__(self, key, value): # if the key is not already defined, add to the # list of keys. if key not in self: self.member_names.append(key) # Call superclass dict.__setitem__(self, key, value) # The metaclass class OrderedClass(type): # The prepare function @classmethod def __prepare__(metacls, name, bases): # No keywords in this case return member_table() # The metaclass invocation def __new__(cls, name, bases, classdict): # Note that we replace the classdict with a regular # dict before passing it to the superclass, so that we # don't continue to record member names after the class # has been created. result = type.__new__(cls, name, bases, dict(classdict)) result.member_names = classdict.member_names return result class MyClass(metaclass=OrderedClass): # method1 goes in array element 0 def method1(self): pass # method2 goes in array element 1 def method2(self): pass x = MyClass() print([name for name in x.member_names if hasattr(getattr(x, name), '__call__')]) 
+1
source share

There is probably one of the shortest methods (class name C):

 for func in filter(lambda x: callable(x), C.__dict__.values()): pass # here func is the next function, you can execute it here 

The filter expression returns all functions of class C.

OR in one line:

 [func() for func in filter(lambda x: callable(x), C.__dict__.values())] 

You can sort the functions in some way, for example, by the lexicographic order of their names with a slightly more complex expression.

+1
source share

All Articles