Asaf
Asaf

Reputation: 8206

Go through a number of functions in Python

I have an unknown number of functions in my python script (well, it is known, but not constant) that start with site_... I was wondering if there's a way to go through all of these functions in some main function that calls for them. something like:

foreach function_that_has_site_ as coolfunc
   if coolfunc(blabla,yada) == true:
      return coolfunc(blabla,yada)

so it would go through them all until it gets something that's true.

thanks!

Upvotes: 3

Views: 238

Answers (6)

Alex Martelli
Alex Martelli

Reputation: 881557

The inspect module, already mentioned in other answers, is especially handy because you get to easily filter the names and values of objects you care about. inspect.getmembers takes two arguments: the object whose members you're exploring, and a predicate (a function returning bool) which will accept (return True for) only the objects you care about.

To get "the object that is this module" you need the following well-known idiom:

import sys
this_module = sys.modules[__name__]

In your predicate, you want to select only objects which are functions and have names that start with site_:

import inspect
def function_that_has_site(f):
    return inspect.isfunction(f) and f.__name__.startswith('site_')

With these two items in hand, your loop becomes:

for n, coolfunc in inspect.getmembers(this_module, function_that_has_site):
   result = coolfunc(blabla, yada)
   if result: return result

I have also split the loop body so that each function is called only once (which both saves time and is a safer approach, avoiding possible side effects)... as well as rewording it in Python;-)

Upvotes: 5

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798516

It's best to use a decorator to enumerate the functions you care about:

_funcs = []

def enumfunc(func):
  _funcs.append(func)
  return func

@enumfunc
def a():
  print 'foo'

@enumfunc
def b():
  print 'bar'

@enumfunc
def c():
  print 'baz'

if __name__ == '__main__':
  for f in _funcs:
    f()

Upvotes: 1

kmerenkov
kmerenkov

Reputation: 2889

def run():
    for f_name, f in globals().iteritems():
        if not f_name.startswith('site_'):
            continue
        x = f()
        if x:
            return x

Upvotes: 1

Trey Hunner
Trey Hunner

Reputation: 11804

This method goes through all properties of the current module and executes all functions it finds with a name starting with site_:

import sys
import types
for elm in dir():
    f = getattr(sys.modules[__name__], elm)
    if isinstance(f, types.FunctionType) and f.__name__[:5] == "site_":
        f()

The function-type check is unnecessary if only functions are have names starting with site_.

Upvotes: 1

Messa
Messa

Reputation: 25181

Try dir(), globals() or locals(). Or inspect module (as mentioned above).

def site_foo():
  pass

def site_bar():
  pass

for name, f in globals().items():
  if name.startswith("site_"):
    print name, f()

Upvotes: 0

Robben_Ford_Fan_boy
Robben_Ford_Fan_boy

Reputation: 8720

Have you tried using the inspect module?

http://docs.python.org/library/inspect.html

The following will return the methods:

inspect.getmembers

Then you could invoke with:

methodobjToInvoke = getattr(classObj, methodName) 
methodobj("arguments") 

Upvotes: 3

Related Questions