qwerty
qwerty

Reputation: 680

How to add a function call to a list?

I have a Python code that uses the following functions:

def func1(arguments a, b, c):

def func2(arguments d, e, f):

def func3(arguments g, h, i):

Each of the above functions configures a CLI command on a product.

In addition, for each of the above functions, there is the de-init function which deletes the CLI command.

def de_init_func1(arguments x, y, z):

def de_init_func2(arguments l, m, n):

def de_init_func3(arguments q, r, s):

Suppose I have a script which configures lots of CLI commands using the functions func1, func2 and func3, and before the script completes, the script should remove all the CLI commands that it configured.

For this to happen, each time func1/2/3 is invoked, I need to add the equivalent de_init_func CALL to a list, so by the end of the script, I can iterate this list, and invoke the de-init methods one by one.

How can I add a "func1(arguments) call" to a list without invoking it while adding it to the list.

If I will just add the func1(arguments) call as a string "func1(arguments)", once I will iterate the list, I won`t be able to invoke the function calls because interpreter will refer to the list items as strings and not as function calls...

Upvotes: 7

Views: 14454

Answers (5)

user3876129
user3876129

Reputation: 21

I think you should use class ; funcx as contructor (__init__) and de_init_funcx as destructor (__del__).

class Class1:
    def __init__( self, arguments, a, b ,c ):
        ...

    def __del__( self, arguments, x, y, z ):
        ...

Upvotes: 1

bereal
bereal

Reputation: 34282

I'd suggest using functools.partial:

from functools import partial

L.append(partial(de_init_func1, x, y, z))
L.append(partial(de_init_func2, l, m, n))

for f in L:
    f()

This supports kwargs if needed. Also, if there are shared arguments for the functions or some are unknown in the beginning, you can postpone their passing until the final call.

Upvotes: 1

Paul
Paul

Reputation: 27423

How can I add a "func1(arguments) call" to a list without invoking it while adding it to the list.

There are at least two ways:

def test(x):
    print "arg was "+str(x)
toDoList = []
args = ["hello"]
toDoList.append(lambda:test(*args))
# doesn't run yet
# run it
for f in toDoList:
    f()

If you think you might want to inspect or change the args before running, this next one is better:

def test(x):
    print "arg was "+str(x)
toDoList = []
args = ["hello"]
toDoList.append({'f': test, 'a': args})
# to run
for item in toDoList:
     item['f'](*item['a'])

Upvotes: 2

Serge Ballesta
Serge Ballesta

Reputation: 148890

At the simplest level, you can simply use tuples for referencing function calls. For example, a call to func1(a, b, c) would be referenced by the tuple (func1, a, b, c). You can then safely put those tuples in a list.

To execute later the function represented by such a tuple (say t), simply use :

t[0](*t[1:])

That is : call the function in t[0] with the arguments in the remaining of typle.

Upvotes: 11

John Zwinck
John Zwinck

Reputation: 249133

You can do this:

setup = [func1, func2, func3]
teardown = [de_init_func1, de_init_func2, de_init_func3]

map(lambda func: func(arguments), setup) # calls all the setup functions
map(lambda func: func(arguments, teardown) # calls all the teardown functions

Upvotes: 0

Related Questions