1

Given there is a list of function's names as strings, would it be possible to call corresponding function with random sampling from the list? Currently I am hard coding all the name by if statement so that

def a(x):
    print(x)

def b(y):
    print(y)
# there are more functions

func_list = ['a', 'b', ...] # all function's names are stored

chosen_function = random.choice(func_list)
if chosen_function == 'a':
    a(1)
elif chosen_function == 'b':
    b(2)
# elif continues...

I want to eliminates all if statements so that whenever I add new functions in func_list, I do not need to modify the if statements.

However, I can not contain the function itself in the list as the actual functions have randomness in them so I need to call it after the function is sampled.

TFC
  • 466
  • 1
  • 5
  • 14
  • "However, I can not contain the function itself in the list as the actual functions have randomness in them so I need to call it after the function is sampled." Could you clarify that? – ssp Jan 07 '21 at 05:42
  • You won't call a function by merely including it in a `list`. `func_list = [a, b]` would work exactly the same way as your `if` block. – Selcuk Jan 07 '21 at 05:43

4 Answers4

3

Why not use a dictionary?

def a(x):
    print(x)

def b(y):
    print(y)

func_dict = {'a': a, 'b': b}

Call it like this:

x = 3 # your int input
func_dict['a'](x) # calls a(x)
func_dict['b'](x) # calls b(x)

If you want to directly specify arguments, you can do so in the dictionary like this:

func_dict = {
    'a': lambda: a(1),
    'b': lambda: b(2)
}

Call the default methods like:

func_dict['a']() # calls a(1)
func_dict['b']() # calls b(2)
Jarvis
  • 8,494
  • 3
  • 27
  • 58
3

The answer of @Jarvis is the right way to go, but for completeness sake, I'll show a different way: inspecting the global variables.

def a(x):
    print(x)

def b(y):
    print(y)
# there are more functions

func_list = ['a', 'b', ...] # all function's names are stored

chosen_function = random.choice(func_list)

globals()[chosen_function](x)
Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
0

You may consider using eval function. In a nutshell, it evaluates a string into a Python snippet.

For example, in the below code, the eval function evaluates any as a string and interprets to python's any built-in function.

>>> eval('any')
>>> <built-in function any>

On similar grounds, you could evaluate the intended function from a string as below.

def function_a(): 
    print('function A')

def function_b(): 
    print('function B')

function_to_run = eval('function_b')    # function_to_run is a callable now
function_to_run()    

Result

function B
Swadhikar
  • 2,152
  • 1
  • 19
  • 32
  • 1
    Use of `eval` should be highly discouraged. It's [dangerous and a bad practice](https://stackoverflow.com/questions/1832940/why-is-using-eval-a-bad-practice). – Jarvis Jan 07 '21 at 05:56
  • @Jarvis agree. How do you think that code in the question is vulnerable to eval? – Swadhikar Jan 07 '21 at 06:11
-1

you can set the default value in the function itself

def a(x=1):
    print(x)

def b(y=2):
    print(y)


chosen_function = random.choice(func_list)

chosen_function()
sammy
  • 427
  • 1
  • 3
  • 14