1

I'm taking in an input from the user and storing it in a variable called videoType.

My question is, how do I take the string the user gives to videoType and convert that into a function name that I already have defined along with many others in python?

Ex. user input: "get_MPEG()" which is stored in videoType

And I would use that input as a function name.

KenB
  • 101
  • 7
  • Create a dictionary from strings to your functions. – juanpa.arrivillaga Mar 02 '18 at 17:46
  • if it's in another module `getattr(module, "method_name")()` but if it is in the same module, you have to do it like this https://stackoverflow.com/a/7936588/5203563, but could be dangerous as mentioned in one of the answers. – Alex028502 Mar 02 '18 at 17:48
  • Give a [**Minimal, Complete, Verifiable** Example](https://stackoverflow.com/help/how-to-ask) in your question. – Alex Mar 02 '18 at 17:49

3 Answers3

4

I would create a dictionary. The keys to the dictionary are user inputs, the values are functions. Something like this:

def compliment():
    print("You look nice today.")

def insult():
    print("You look awful today.")

def default_function():
    print("Sorry, I don't know what you mean")

functions = {
    "compliment": compliment,
    "nice": compliment, # aliased command
    "insult": insult,
    "mean": insult,
}

videoType = input("What shall I do? ")
functions.get(videoType, default_function)()

Whatever you do, do NOT directly convert the user's input to code. Consider what happens if the user inputs os.system('rm -rf' /) as the name of his function!

Robᵩ
  • 163,533
  • 20
  • 239
  • 308
2

You can make a dictionary mapping function names to their corresponding functions:

def foo():
    print('foo called')

def bar():
    print('bar called')


exposed_functions = {
    'foo': foo,
    'bar': bar
}

if __name__ == '__main__':
    user_input = 'foo'  # Pretend the user passed you this string
    function = exposed_functions[user_input]
    function()

This approach may seem redundant but you probably don't want the user to pass in a function like exit() and shut down your interpreter or even something like __import__('os').system('rm -Rf --no-preserve-root /') and do more harm. Therefore, a whitelist is your best choice. To make it simpler, you can create a decorator to do all of this for you:

import functools

exposed_functions = {}

def expose(*names):
    def decorator(function):
        for name in (names or [function.__name__]):
            exposed_functions[name] = function

        return function

    return decorator

@expose()  # `name` is automatically extracted out of the function
def foo():
    print('foo called')

@expose('bar', 'baz')  # binds to both `bar` and `baz`
def bar():
    print('bar called')

if __name__ == '__main__':
    user_input = 'baz'  # Pretend the user passed you this string
    function = exposed_functions[user_input]
    function()
Blender
  • 289,723
  • 53
  • 439
  • 496
  • The decorator is a good idea! – Robᵩ Mar 02 '18 at 17:50
  • do I not need parantheses around the function names in the dictionary for your first example, for example 'foo' : foo() – KenB Mar 05 '18 at 20:08
  • @KenB: `foo` is the function itself, `foo()` is the result of calling your function. You don't need to call the function, just reference it. For example, `x = foo; x()` is the same as `foo()`. – Blender Mar 07 '18 at 04:19
0

You can also use globals() dictionary to access all the defined top-level functions (as well as other objects) in a module

def hello():
    print('hello')


videoType = input("Name a function")
globals()[videoType)()
Brendan Abel
  • 35,343
  • 14
  • 88
  • 118