calling a function from string

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Mon Oct 22 19:16:38 EDT 2007


On Mon, 22 Oct 2007 08:54:02 +0000, james_027 wrote:

> hi,
> 
> i have a function that I could like to call, but to make it more dynamic
> I am constructing a string first that could equivalent to the name of
> the function I wish to call. 

That is not the right solution to dynamic functions. There is a much 
better way.


> how could I do that? the string could might
> include name of the module.
> 
> for example
> 
> a_string = 'datetime.' + 'today()'
> 
> how could I call a_string as function?

Others have suggested eval() and exec. Both will work, but have MAJOR 
security implications.

The right way to work with "dynamic functions" is to remember that Python 
treats functions as first-class objects just like strings and ints and 
lists. Here's a simple example:

Suppose I have a function that takes a string and converts it to another 
object type. 

def converter(x, convert_to):
    if convert_to == 'int':
        return int(x)
    elif convert_to == 'float':
        return float(x)
    elif convert_to == 'list':
        return list(x)
    else:
        raise ValueError("don't know that type")

and then use the function like this:

my_float = converter('12.345', 'float')


That's the wrong way to do it. This is the right way:

def converter(x, convert_to):
    return convert_to(x)

my_float = converter('12.345', float)

See the subtle difference?

'float' is a string, and it has no special meaning.

float() with brackets says "call the function float".

float without brackets *is* the function float. You can pass it around 
like any other object (strings, lists, ints, etc.) and call it later.

Try this example:

import datetime, time
functions = [int, float, datetime.time, time.time]
for f in functions:
    print f()



-- 
Steven



More information about the Python-list mailing list