how can I execute a function string

Discussion in 'Python' started by Rajarshi Guha, Jan 13, 2004.

  1. 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,
     
    Rajarshi Guha, Jan 13, 2004
    #1
    1. Advertising

  2. 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
     
    Francis Avila, Jan 13, 2004
    #2
    1. Advertising

  3. Rajarshi Guha

    Hans Nowak Guest

    Rajarshi Guha wrote:

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

    >>> def generate_func():

    .... s = """def f(x):
    .... print x
    .... return 2"""
    .... d = {}
    .... exec s in d
    .... return d['f']
    ....
    >>>
    >>> g = generate_func()
    >>> g(4)

    4
    2
    >>>


    ....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:

    >>> def generate_func():

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

    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 generate_func():

    .... def f(x):
    .... print x
    .... return 2
    .... return f
    ....
    >>> h = generate_func()
    >>> h(5)

    5
    2

    HTH,

    --
    Hans ()
    http://zephyrfalcon.org/
     
    Hans Nowak, Jan 13, 2004
    #3
  4. On Mon, 12 Jan 2004 21:23:20 -0500, Francis Avila wrote:

    > 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
     
    Rajarshi Guha, Jan 14, 2004
    #4
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jim Hammond
    Replies:
    2
    Views:
    4,525
    bruce barker
    Nov 14, 2003
  2. Dan Pop

    Re: To execute a string as function

    Dan Pop, Jun 24, 2003, in forum: C Programming
    Replies:
    6
    Views:
    4,318
    Richard Heathfield
    Jun 24, 2003
  3. Larry__Weiss

    Re: To execute a string as function

    Larry__Weiss, Jun 24, 2003, in forum: C Programming
    Replies:
    0
    Views:
    744
    Larry__Weiss
    Jun 24, 2003
  4. TheDustbustr
    Replies:
    1
    Views:
    461
    Sami Hangaslammi
    Jul 25, 2003
  5. Savas Ates
    Replies:
    1
    Views:
    287
    Patrice
    Aug 17, 2004
Loading...

Share This Page