Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python constructing functions on the fly

Tags:

python

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?

like image 627
netimen Avatar asked Oct 20 '09 09:10

netimen


2 Answers

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.

like image 129
Greg Hewgill Avatar answered Oct 04 '22 18:10

Greg Hewgill


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)
like image 36
Stephan202 Avatar answered Oct 04 '22 16:10

Stephan202