I have a string whose content is a function name, how to refer to the corresponding function in Python?

For example, if I have a function called add like

def add(x,y):
    return x+y

and I want the ability to convert a string or an input to direct to that function like

w=raw_input('Please input the function you want to use')

or

w='add'

Is there any way to use w to refer to the function add?


Solution 1:

Since you are taking user input, the safest way is to define exactly what is valid input:

dispatcher={'add':add}
w='add'
try:
    function=dispatcher[w]
except KeyError:
    raise ValueError('invalid input')

If you want to evaluate strings like 'add(3,4)', you could use safe eval:

eval('add(3,4)',{'__builtins__':None},dispatcher)

eval in general could be dangerous when applied to user input. The above is safer since __builtins__ is disabled and locals is restricted to dispatcher. Someone cleverer than I might be able to still cause trouble, but I couldn't tell you how to do it.

WARNING: Even eval(..., {'__builtins__':None}, dispatcher) is unsafe to be applied to user input. A malicious user could run arbitrary functions on your machine if given the opportunity to have his string evaluated by eval.

Solution 2:

One safe way is to map from names to functions. It's safer than using eval.

function_mappings = {
        'add': add,
}

def select_function():
    while True:
        try:
            return function_mappings[raw_input('Please input the function you want to use')]
        except KeyError:
            print 'Invalid function, try again.'

Solution 3:

The built-in function eval will do what you want. All the usual warnings about executing arbitrary user-supplied code apply.

If there are a finite number of predefined functions, you should avoid eval and use a lookup table instead (i.e. Dict). Never trust your users.