tags:

views:

162

answers:

5

I have several little functions f1, f2, f3 and a function f.

I want f to be a "container" to f1, f2, f3: to do the some of operations f1, f2, f3, depending on the program configuration (for example f1 and f2 or f1 and f3 or all the three) and nothing more.

I see two simple solutions: first to add some if's in the function f:

if configuration_f1_f2:
    f1()
    f2()

second, I can add a list of operations in f:

for op in operations:
    op()

and add f1, f2, f3 in operations or remove them, depending on configuration.

But can I somehow construct dynamically code of 'f' adding to it calls of f1, f2 and f3 exact what I need without any if's or list's or for's? I mean something like on the fly code manipulation. So if my configuration is "f1 and f3", I set code of f so that it is

f1()
f3()

and when my configuration changes to "f2 and f3" I modify code of f to

f2()
f3()

Can I manipulate the code of the function that way?

+1  A: 

Create dictionary

fun_dict = {'f1': f1, 'f2': f2}

then parse your config and run function from dict:

fun_dict[parsed_name]()
Michał Niklas
+3  A: 

If f1, f2 etc. are functions with side effects, than you should use an explicit for loop (no fancy map solution). Perhaps you want something like this?

configurations = {
  'config_1': (f1, f2, f3),
  'config_2': (f1, f2),
}

def f(config='config_1'):
    for op in configurations[config]:
        op()

If f1, f2 etc. receive arguments, then perhaps this is a more suitable definition of f:

def f(config, *args, **kwargs):
    for op in configurations[config]:
        op(*args, **kwargs)
Stephan202
+1  A: 

There can be various ways to achieve what you want, but for that you need to fully define the problem and context

a way could be like this, and most of the other will be variant of this, using a dict to lookup the function we need

def f1(): print "f1"
def f2(): print "f2"
def f3(): print "f3"

def f(fList):
    for f in fList: globals()[f]()

f(["f1", "f2"])
f("f1 f3 f1 f3 f2 f1 f3 f2".split())
Anurag Uniyal
why do you need a list of strings? this would work as well:def f(*flist): [x() for x in flist]f(f1, f2)
Martin DeMello
because OP was talking abt config, where values will be strings
Anurag Uniyal
+2  A: 

If you're brave, you can construct a function definition as a string and pass it to the exec statement. For example:

func = "def f():\n"
if config_f1:
    func += " f1()\n"
if config_f2:
    func += " f2()\n"
exec func in globals()

At this point, you should have a new global f() that executes the appropriate bits of code.

Greg Hewgill
Thank you! this seems to be the best solution!
netimen
+1  A: 

Use objects and the Command design pattern.

class Function( object ):
    pass

class F1( Function ):
    def __call__( self ):
        whatever `f1` used to do

 class F2( Function ):
    def __call__( self ):
        whatever `f1` used to do

 class Sequence( Function ):
     def __init__( self, *someList ):
         self.sequence= someList
     def __call__( self ):
         for f in self.sequence:
             f()

f= myDynamicOperation( F1(), F2(), F3() )
f()

That's how it's done. No "constructing a function on the fly"

S.Lott
but how is it different from calling f1(), f2(), f3(); directly
Anurag Uniyal