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.

2
  • "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? Commented Jan 7, 2021 at 5: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. Commented Jan 7, 2021 at 5:43

4 Answers 4

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)
Sign up to request clarification or add additional context in comments.

Comments

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)

Comments

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

2 Comments

Use of eval should be highly discouraged. It's dangerous and a bad practice.
@Jarvis agree. How do you think that code in the question is vulnerable to eval?
-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()

1 Comment

chosen_function is a string, not a callable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.