how can I execute a function string
Francis Avila
francisgavila at yahoo.com
Mon Jan 12 21:23:20 EST 2004
Rajarshi Guha wrote in message ...
>Hi ,
> I have some code that generates a function on the fly in a string.
>At a later point in time I want to execute this function (which also
>requires a parameters to be passed to it). So the code is something like
>this:
>
>def generate_func():
> s = """ def function(x):
> print x
> return 2
>"""
> return s
>
>funcstring = generate_func()
>retval = ....
>
>That is, retval should have the value returned from the evaluation of the
>function in the string funcstring.
>
>Is this possible by means of simple function calls or does this involve
>some sort of black magic?
>
>Thanks,
What is it with code-generation this week?
Anyway, the exec statement (not function) will execute the contents of a
string or code object as though it were inline code:
E.g.:
>>> x
Traceback (most recent call last):
...
NameError: name 'x' is not defined
>>> exec 'x = 1'
>>> x
1
>>>
Use like so:
exec generate_func()
# 'function' is now in your namespace.
function('hello') # should print 'hello' and return 2.
A *slightly* better approach is to make a code object, using compile().
def gen_func():
s = '''
def f(x):
return x
'''
return compile(s, '<source>', 'single')
exec gen_func() # f gets dumped into your namespace.
If you're very ambitious, you can generate an AST tree and compile that: see
the compile module. In this simple case there's no advantage, however.
I'll have to think about how to turn the raw source of a function definition
into a callable. I'm not sure it's possible in a 100% reliable manner.
Here's a first attempt (untested):
def makecallable(source):
"""Return a function from string source.
'def <funcname>' must be the first tokens in source!
"""
co = compile(source, '<makecallable()>', 'single')
funcname = co.co_varnames[0] #This is VERY brittle!!
fakelocals = {}
exec co in globals(), fakelocals
return fakelocals[funcname]
Now that I've told you about exec, I'll tell you that you almost certainly
shouldn't be using it. There is most likely a better way to do what you're
doing than building code strings and executing them. Python has a lot of
reflection, introspection, and dynamic object generation capabilities, which
generally remove the need for using exec, which is slow, hackish, and
error-prone. Please tell us more about what you're doing.
--
Francis Avila
More information about the Python-list
mailing list