How to randomly choose method from a list of methods with different arguments?

Viewed 435

I have object a of class b with methods foo(), boo(), noo(arg). Now I want to randomly choose one of them without extending the class b. The problem is that if I use technics supposed here: Syntax to call random function from a list , then I have to have the same arguments of my methods. So I can't use smth like this:

my_list = [a.foo, a.boo, a.noo]    
random.choice(my_list)()

I case of noo method I need to call it with arg: a.noo(arg). So how to do it in pythonic way?

3 Answers
import random

funcs = [foo, boo, noo]
args = [[1,2,3], [4,5], [2]]
choice = random.randint(len(funcs))

funcs[choice](*args[choice])

This way you have the flexibility to call any function with dynamic arguments, depending on your methods.

Remember to keep the arguments and the functions in the same order

Edit: You can also do as suggested in the comments (which i think it's easier, thank you!):

import random

calls = [(foo, [1,2,3]), (boo, [4,5]), (noo, [2])]
choice = random.choice(calls)

choice[0](*choice[1])

This is how I would do it. Although if you want to have functions with more than 1 argument it's probably best to send it as a list and unpack it at the function.

import random

def foo():
    print('foo')

def boo():
    print('boo')

def noo(arg):
    print('noo:', arg)

my_list = [(foo,), (boo,), (noo, 'hello world')]
for i in range(10):
    choice = random.choice(my_list)
    if len(choice) == 1:
        choice[0]()
    else:
        choice[0](choice[1])

Something like this was suggested in comment:

import random

my_list = [a.foo, a.boo, a.noo]  
rand = random.choice(my_list)
if rand.__name__ == 'noo':
    rand(arg)
else:
    rand()
Related