0

I need to call a function based off the value of a string variable.

mystrvar = 'a'

def a():
  print("Hello, world!")

mystrvar()

In that example, I would like function a() to be called, because that's the value of mystrvar.

Hope this makes sense :)

parkero2
  • 21
  • 1
  • 1
    Does this answer your question? [Calling a function of a module by using its name (a string)](https://stackoverflow.com/questions/3061/calling-a-function-of-a-module-by-using-its-name-a-string) – thshea Dec 06 '20 at 23:15
  • 1
    This is often not the best approach. What are you actually trying to achieve? – anon01 Dec 06 '20 at 23:21

2 Answers2

3

This type of question comes up a lot on StackOverflow and is most often the result of people not really getting the difference between data and code.

You typically don't want users of your program to have to know what the code of the program is to be able to use it.

So, instead of magically calling a() when the string 'a' is entered, it's generally better to code explicitly that a() will be called with 'a' is entered.

Here's some code explaining the difference:

def a():
    print('running a')


def b():
    print('running b')


def c():
    print('this should not be run!')


choice = input('a or b?')
if choice == 'a':
    a()
elif choice == 'b':
    b()

choice = input('a or b?')
eval(f'{choice}()')

Note how only 'a' or 'b' do something after the first prompt, but you can enter 'c' on the second prompt, even if you would only ever want the user to run a or b.

Even worse, what do you think happens if the user enters wipe_my_c_drive and you happen to have a function that does just that?

Also, if you later replace your function a() with a new function called new_a(), your program can work the same for your users if you use the first method, while the second method requires your user to know the name has changed.

Grismar
  • 27,561
  • 4
  • 31
  • 54
  • 1
    good answer, but rather than the multiple `if` statements, I would use a dictionary of `{'a':a,'b':b}` as it scales better and is easier to update, you can also pass that dict around if you ever need to. – JeffUK Dec 06 '20 at 23:20
  • 2
    Agreed @JeffUK - but I figured that someone struggling with this type of problem that hasn't yet found `eval()`, may need to learn about `dict` still as well. But you're absolutely right that maintaining multiple options in an `if .. elif .. else ..` structure is a bad practice to grow beyond a few options. – Grismar Dec 06 '20 at 23:27
0

Your code is good, the only problem is that when you try to call the function, mystrvar is a string. Instead, it should be equal to the name of that function, because functions are data types and if you set mystrvar equal to a function name, you are telling it that when you call mystrvar you are calling a().

In the example below, first a() function will be executed and then b()

def a():
    print('Hi')

def b():
    print('Hello world')

myfunctionvar = a

myfunctionvar()

myfunctionvar = b

myfunctionvar()
Dharman
  • 30,962
  • 25
  • 85
  • 135
PoliPau
  • 1
  • 1
  • 4