Mahdi Yusuf
Mahdi Yusuf

Reputation: 21038

Running bunch of python methods on a single piece of data

I would like to run a set of methods given some data. I was wondering how I can remove or chose to run different methods to be run. I would like to groups them within a larger method so I can call it; and it will go along the lines of test case.

In code: Now these are the methods that process the data. I may sometimes want to run all three or a subset thereof to collect information on this data set.

def one(self):
    pass
def two(self):
    pass
def three(self):
    pass

I would like to be able to call of these methods with another call so I dont have to type out run this; run this. I am looking for elegant way to run a bunch of methods through one call so I can pick and choose which gets run.

Desired result

def run_methods(self, variables):
     #runs all three or subset of

I hope I have been clear in my question. I am just looking for an elegant way to do this. Like in Java with reflection.

Please and thanks.

Upvotes: 0

Views: 141

Answers (3)

joaquin
joaquin

Reputation: 85683

Send the methods you want to run as a parameter:

def runmethods(self, variables, methods):
   for method in methods:
       method(variables)

then call something like:

self.runmethods(variables, (method1, method2))

This is the nice thing of having functions as first-class objects in Python

For the question of the OP in the comment (different parameters for the functions), a dirty solution (sorry for that):

def rest(a, b):
    print a - b

def sum(a, b):
    print a + b

def run(adictio):
    for method, (a, b) in adictio.iteritems():
        method(a, b)

mydictio = {rest:(3, 2), sum:(4, 5)}

run(mydictio)

You could use other containers to send methods together with their variables but it is nice to see a function as the key of a dictionary

if your methods/functions use different numbers of parameters you can not use

for method, (a,b) in adictio.iteritems():

because it expects the same number of parameters for all methods. In this case you can use *args:

def rest(*args):
    a, b = args
    print a - b

def sum(*args):
    a, b, c, d, e = args
    print a + b + c + d + e

def run(adictio):
    for method, params in adictio.iteritems():
        method(*params)

mydictio = {rest:(3, 2), sum:(4, 5, 6, 7, 8)}

run(mydictio)

Upvotes: 4

Josh Smeaton
Josh Smeaton

Reputation: 48730

To answer the question in the comment regarding passing arbitrary values:

def runmethods(self, methods):
   for method, args in methods.iteritems():
       method(*args[0], **args[1])

runmethods( {methodA: ([arg1, arg2], {'kwarg1:' 'one', 'kwarg2'})},
            {methodB: ([arg1], {'kwarg1:' 'one'})} 
          )

But at this point, it's looking like more code than it's worth!

Upvotes: 1

Mike M. Lin
Mike M. Lin

Reputation: 10072

If you normally do all the functions but sometimes have exceptions, then it would be useful to have them done by default, but optionally disable them like this:

def doWalkDog():
    pass

def doFeedKid():
    pass

def doTakeOutTrash():
    pass

def doChores(walkDog=True, feedKid=True, takeOutTrash=True):
    if walkDog: doWalkDog()
    if feedKid: doFeedKid()
    if takeOutTrash: doTakeOutTrash()

# if the kid is at grandma's...
# we still walk the dog and take out the trash
doChores(feedKid=False)

Upvotes: 2

Related Questions