dynamic construction of variables / function names

Steven D'Aprano steve at REMOVEMEcyber.com.au
Thu Mar 30 10:24:10 CEST 2006

Sakcee wrote:

> python provides a great way of dynamically creating fuctions calls and
> class names from string
> a function/class name can be stored as string and called/initilzed
> e.g
> def foo(a,b):
>     return a+b
> def blah(c,d):
>     return c*d
> list = ["foo", "blah"]
> for func in list:
> 	print func(2,4)
> or similar items

Have you actually tried to do this? It doesn't work:

Traceback (most recent call last):
   File "<stdin>", line 2, in ?
TypeError: object of type 'string' is not callable

(Also, it is poor practice to shadow the built-in list 
as you have.)

You are attempting to call "foo"(2, 4). Strings are not 

Two ways to actually do what you are trying to do is 
with eval and exec:

 >>> eval("foo(2, 3)")
 >>> exec("print foo(2, 3)")

but be aware of the possible security implications of 
eval and exec.

If you are calling instance methods, you can use getattr:

 >>> class Foo:
...     def foo(self, x,y):
...             return x+y
 >>> getattr(Foo(), "foo")(2, 3)

But the best way is, if possible, avoid this altogether 
and remember that functions are first-class objects in 
Python. Instead of doing this:

L = ["foo", "bar"]
for func in L:
     print eval(func + "(2, 3)")

do this:

L = [foo, bar]  # list containing function objects
for func in L:
     print func(2, 3)

> what is the way if the names of functions are some modification e.g

As far as I know, the only ways are: use eval or exec, 
or look in locals and/or globals:

 >>> func = locals().get("f" + "oo", None)
 >>> if callable(func):
...     func(2, 3)

You can use globals() instead of locals(), but there 
may be issues with scoping rules that I can't think of.

Personally, I think the best way is: find another way 
to solve your problem.

> is it correct way, is there a simple way, is this techniqe has a name?

I'm told that some people call this "dynamic 
programming", but personally I call it "difficult to 
maintain, difficult to debug programming".

(Before people get all cranky at me, I'm aware that it 
isn't *always* the Wrong Way to solve problems, but it 
is a technique which is subject to abuse and can often 
be avoided by using function objects instead of 
function names.)


More information about the Python-list mailing list