Re: how can I execute a function string

From: Francis Avila (francisgavila_at_yahoo.com)
Date: 01/13/04


Date: Mon, 12 Jan 2004 21:23:20 -0500

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


Relevant Pages

  • Re: func_code vs. string problem
    ... # we define 'print b' in three different ways: as a string, ... def execstring(): ... exec function.func_code ... strings and pass around as compiled objects, ...
    (comp.lang.python)
  • XML Update Question
    ... I am having trouble updating a row that has a string value for a bit column. ... Below I have given my table def, stored proc and sample data. ... EXEC sp_xml_preparedocument @hDoc OUTPUT, @XMLEmp ...
    (microsoft.public.sqlserver.programming)
  • Re: Multi-line "Srchfor" Utility?
    ... specified on the command. ... for each EXEC CICS command, that literal is a bit string (arg 0 in the ... EXEC CICS GETMAIN, but beyond that I'd need to refer to the CICS Data ...
    (bit.listserv.ibm-main)
  • Re: Winter Madness - Passing Python objects as Strings
    ... "seldom" here is like once a day for a few minutes. ... name as a string and mucking around with exec or eval - ... for the exec to work. ... precious cycles in an extra unpacking stage. ...
    (comp.lang.python)
  • Re: Is Perl *that* good?
    ... >> I rarely compile regexps, just pass the string to the re functions. ... def match: ...
    (comp.lang.python)