how can I execute a function string

R

Rajarshi Guha

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,
 
F

Francis Avila

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.:Traceback (most recent call last):
....
NameError: name 'x' is not defined
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.
 
H

Hans Nowak

Rajarshi said:
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?

It's possible:
.... s = """def f(x):
.... print x
.... return 2"""
.... d = {}
.... exec s in d
.... return d['f']
....

....but this way of doing it has several drawbacks. For example, exec is picky
about the strings it accepts; e.g. if you leave a trailing newline you get a
syntax error. Compare:
.... s = """def f(x):
.... print x
.... return 2
.... """
.... d = {}
.... exec s in d
.... return d['f']
....Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 7, in generate_func
File "<string>", line 4

^
SyntaxError: invalid syntax

Also, if the string containing the syntax comes from an "untrusted source",
then it's a potential security hazard.

I'm not sure what you're trying to do here, but you might want to consider
generating an actual function, rather than a string to be evaluated:
.... def f(x):
.... print x
.... return 2
.... return f
....5
2

HTH,
 
R

Rajarshi Guha

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:
[
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]

Well I was playing with Andrews curves which allows one to visualize a
vector of numbers in terms of a Fourier series. So basically I was
creating a string that ontained the Fourier representation of the vector
and then evaluating the resultant function.

I know this can be done simpler using loops - I jst wanted to see how I
could do this using a bit of code generation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top