By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
426,165 Members | 1,928 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 426,165 IT Pros & Developers. It's quick & easy.

Getting a function name from string

P: n/a
If I have a string that contains the name of a function, can I call it?
As in:

def someFunction():
print "Hello"

s = "someFunction"
s() # I know this is wrong, but you get the idea...

/David
Nov 2 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a
"David Rasmussen" <da*************@gmx.net> wrote in message
news:43**********************@dtext02.news.tele.dk ...
If I have a string that contains the name of a function, can I call it?
As in:

def someFunction():
print "Hello"

s = "someFunction"
s() # I know this is wrong, but you get the idea...

/David


Lookup the function in the vars() dictionary.
def fn(x): .... return x*x
.... vars()['fn'] <function fn at 0x009D67B0> vars()['fn'](100)

10000

-- Paul
Nov 2 '05 #2

P: n/a
"Paul McGuire" <pt***@austin.rr._bogus_.com> writes:
"David Rasmussen" <da*************@gmx.net> wrote in message
news:43**********************@dtext02.news.tele.dk ...
If I have a string that contains the name of a function, can I call it?
As in:

def someFunction():
print "Hello"

s = "someFunction"
s() # I know this is wrong, but you get the idea...

/David


Lookup the function in the vars() dictionary.
def fn(x): ... return x*x
... vars()['fn'] <function fn at 0x009D67B0> vars()['fn'](100) 10000


vars() sans arguments is just locals, meaning it won't find functions
in the global name space if you use it inside a function:
def fn(x): .... print x
.... def fn2(): .... vars()['fn']('Hello')
.... fn2() Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in fn2
KeyError: 'fn'


Using globals() in this case will work, but then won't find functions
defined in the local name space.

For a lot of uses, it'd be better to build the dictionary by hand
rather than relying on one of the tools that turns a namespace into a
dictionary.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Nov 3 '05 #3

P: n/a
David Rasmussen wrote:
If I have a string that contains the name of a function, can I call it?
As in:

def someFunction():
print "Hello"

s = "someFunction"
s() # I know this is wrong, but you get the idea...


py> eval("someFunction()")
'Hello'
py> eval(s)() # note the second pair of brackets
'Hello'

See also exec -- but before you use either eval or
exec, make sure you are fully aware of the security
implications. Whatever a user could do to your system
by sitting down in front of it with a Python
interactive session open and typing commands at the
keyboard, they can also do remotely if you call exec on
input they provide.

So you probably don't want to be calling exec on
strings that you get from random users via a website.

It has been my experience that, more often than not,
any time you think you want to evaluate strings, you
don't need to.

For instance, instead of passing around the name of the
function as a string:

s = "someFunction"
eval(s)()

you can pass around the function as an object:

s = someFunction # note the lack of brackets
s()

--
Steven.

Nov 3 '05 #4

P: n/a
On Wed, 02 Nov 2005 19:01:46 -0500, Mike Meyer <mw*@mired.org> wrote:
"Paul McGuire" <pt***@austin.rr._bogus_.com> writes:
"David Rasmussen" <da*************@gmx.net> wrote in message
news:43**********************@dtext02.news.tele.dk ...
If I have a string that contains the name of a function, can I call it?
As in:

def someFunction():
print "Hello"

s = "someFunction"
s() # I know this is wrong, but you get the idea...

/David


Lookup the function in the vars() dictionary.
> def fn(x):

... return x*x
...
> vars()['fn']

<function fn at 0x009D67B0>
> vars()['fn'](100)

10000


vars() sans arguments is just locals, meaning it won't find functions
in the global name space if you use it inside a function:
def fn(x):... print x
... def fn2():... vars()['fn']('Hello')
... fn2()Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 2, in fn2
KeyError: 'fn'


Using globals() in this case will work, but then won't find functions
defined in the local name space.

For a lot of uses, it'd be better to build the dictionary by hand
rather than relying on one of the tools that turns a namespace into a
dictionary.

IMO it would be nice if name lookup were as cleanly
controllable and defined as attribute/method lookup.
Is it a topic for py3k?

Regards,
Bengt Richter
Nov 3 '05 #5

P: n/a
bo**@oz.net (Bengt Richter) writes:
For a lot of uses, it'd be better to build the dictionary by hand
rather than relying on one of the tools that turns a namespace into a
dictionary.

IMO it would be nice if name lookup were as cleanly
controllable and defined as attribute/method lookup.
Is it a topic for py3k?


I'm not sure what you mean by "cleanly controllable and defined". I'd
say name lookup is well defined and clean, as it's the same as it is
in pretty much any language that supports nested scopes, modulo
assignment creating things in the local scope. If you're talking about
letting users control that mechanism, that's definitely py3k material,
if not "python-like-language-that's-not-python" material. On the other
hand, if you just want to provide tools that let users do name lookups
the way they can do attribute lookups, that's easy, and we could add
that now:

getname(name) - returns the object name is bound to.
setname(name, value) - binds the variable name.

And maybe you want an optional third argument of a callable, which
causes the functions to work on names starting in the callables name
space.

The real question is (as always) - what's the use case? In particular,
what's the use case that we really want to encourage? As I said,
you're usually better off separating dynamically built names into
their own dictionary rather than trying to plug them into - or pull
them out of - one of the language namespaces. If you plug them in,
there's no way to get them back out except by mechanisms similar to
how you got them in, so you might as well let those mechanisms include
a dictionary. If you pull it out, you might as well have referenced
the bare name rather than the string. If you constructed the name in
some way, then changing the constructor to do a dictionary lookup
should be straightforward. All of these technics avoid problems that
come from overloading a language namespace.

Of course, I'm not omniscient, so you may have something that doesn't
fit those cases in mind - in which case, let's hear about it.

You can even arrange to run python code with your dictionary as a
namespace. Following are excerpts from a tool I'm currently not
working on.

class P:
def __init__(self):
self.variables = dict(In = self.set_input, Out = self.set_output,
Labels = self.set_labels, Float = DoubleVar,
String = StringVar, Int = IntVar)

def calculate(self):
for name, var in self.inputs.items():
self.variables[name] = var.get()
self.variables['calculate']()
for name, var in self.outputs.items():
var.set(self.variables[name])

def run(self):
self.app.mainloop(self.calculate)
def main(args):
app = P()
execfile(argv[1], app.variables)
app.run()

Here I create a dictionnary - P().variables - and populate it with
names and their values. I then run the code of interest with that
dictionary as the global namespace. The code will add things to the
namespace - in particular, "calculate". I then run a loop which will,
at unspecified times, set names in the P().variables dictionary, run
the "calculate" callable created by the code of interest, then copy
values out of the dictionary. This works ilke a charm. If you don't
want to deal with entire files, you can use exec, or even eval if you
just want to get a value back.

<mike
--
Mike Meyer <mw*@mired.org> http://www.mired.org/home/mwm/
Independent WWW/Perforce/FreeBSD/Unix consultant, email for more information.
Nov 3 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.