Building a function call?
Steven D'Aprano
steve at REMOVETHIScyber.com.au
Wed Jul 13 09:55:28 EDT 2005
On Wed, 13 Jul 2005 06:16:54 -0700, Robert Kern wrote:
> Duncan Booth wrote:
>> Francois De Serres wrote:
>>
>>>Having a string: "dothat"
>>>and a tuple: (x, y)
>>>1. What's the best way to build a function call like: dothat(x,y)?
[snip]
>> No, none of this is a good place to use eval.
[snip]
>> import otherModule
>> vars(otherModule)[aString](*aTuple)
>
> Ick! Please:
> getattr(otherModule, aString)(*aTuple)
Or, remember that functions are first class objects in Python. Instead of
passing around the function name as a string, pass around a reference to
the function itself. Something like this:
def dothis(x,y):
return x-y
def dothat(x,y):
return x+y
somefunction = dothis
somefunction(3, 2)
=> returns 1
somefunction = dothat
somefunction(3, 2)
=> returns 5
allfunctions = [dothis, dothat]
for func in allfunctions:
print func(3, 2)
=> prints 1 then 5
If you want to collect user-supplied strings and use them to find a
function, you could use eval (terribly risky and unsafe), or you could do
something like this:
funcnames = {}
for func in allfunctions:
funcnames[func.__name__] = func
F = raw_input("Enter the name of a function: ")
try:
funcnames[F](3, 2)
except KeyError:
print "Function '%s' not found!" % F
In my humble opinion, people muck about with eval, locals and globals far
too often. It is unclear, hard to maintain, and frequently a security
risk. These confusing, unsafe practices can usually be avoided by
remembering that functions are first class objects just like ints, strings
and lists.
--
Steven.
More information about the Python-list
mailing list