how to convert a multiline string to an anonymous function?

Discussion in 'Python' started by Danny Shevitz, Apr 29, 2008.

  1. Simple question here:

    I have a multiline string representing the body of a function. I have control
    over the string, so I can use either of the following:

    str = '''
    print state
    return True
    '''

    str = '''
    def f(state):
    print state
    return True
    '''

    and I want to convert this into the function:

    def f(state):
    print state
    return True

    but return an anonmyous version of it, a la 'return f' so I can assign it
    independently. The body is multiline so lambda doesn't work.

    I sort of need something like:

    def function_constructor(str):
    f = eval(str) # What should this be
    return f

    functions = {}
    for node in nodes:
    function[node] = function_constructor(node.text)

    I'm getting stuck because 'def' doesn't seem to work in an eval function,
    and exec actually modifies the namespace, so I run into collisions if I use
    the function more than once.

    I know I'm missing something stupid here, but I'm stuck just the same...

    thanks,
    Danny
    Danny Shevitz, Apr 29, 2008
    #1
    1. Advertising

  2. Danny Shevitz schrieb:
    > Simple question here:
    >
    > I have a multiline string representing the body of a function. I have control
    > over the string, so I can use either of the following:
    >
    > str = '''
    > print state
    > return True
    > '''
    >
    > str = '''
    > def f(state):
    > print state
    > return True
    > '''
    >
    > and I want to convert this into the function:
    >
    > def f(state):
    > print state
    > return True
    >
    > but return an anonmyous version of it, a la 'return f' so I can assign it
    > independently. The body is multiline so lambda doesn't work.
    >
    > I sort of need something like:
    >
    > def function_constructor(str):
    > f = eval(str) # What should this be
    > return f
    >
    > functions = {}
    > for node in nodes:
    > function[node] = function_constructor(node.text)
    >
    > I'm getting stuck because 'def' doesn't seem to work in an eval function,
    > and exec actually modifies the namespace, so I run into collisions if I use
    > the function more than once.
    >
    > I know I'm missing something stupid here, but I'm stuck just the same...


    The "stupid" thing is that you can pass your own dictionary as globals
    to exec. Then you can get a reference to the function under the name "f"
    in the globals, and store that under whatever name you need.

    Beware of recursion though! If that happens, you need to create unique
    names for your functions, but as you know these beforehand I don't see
    any problem with that - just enumerate them, like f1, f2, f3....

    Diez
    Diez B. Roggisch, Apr 29, 2008
    #2
    1. Advertising

  3. Danny Shevitz

    Matimus Guest

    On Apr 29, 3:39 pm, "Diez B. Roggisch" <> wrote:
    > Danny Shevitz schrieb:
    >
    >
    >
    > > Simple question here:

    >
    > > I have a multiline string representing the body of a function. I have control
    > > over the string, so I can use either of the following:

    >
    > > str = '''
    > > print state
    > > return True
    > > '''

    >
    > > str = '''
    > > def f(state):
    > > print state
    > > return True
    > > '''

    >
    > > and I want to convert this into the function:

    >
    > > def f(state):
    > > print state
    > > return True

    >
    > > but return an anonmyous version of it, a la 'return f' so I can assign it
    > > independently. The body is multiline so lambda doesn't work.

    >
    > > I sort of need something like:

    >
    > > def function_constructor(str):
    > > f = eval(str) # What should this be
    > > return f

    >
    > > functions = {}
    > > for node in nodes:
    > > function[node] = function_constructor(node.text)

    >
    > > I'm getting stuck because 'def' doesn't seem to work in an eval function,
    > > and exec actually modifies the namespace, so I run into collisions if I use
    > > the function more than once.

    >
    > > I know I'm missing something stupid here, but I'm stuck just the same...

    >
    > The "stupid" thing is that you can pass your own dictionary as globals
    > to exec. Then you can get a reference to the function under the name "f"
    > in the globals, and store that under whatever name you need.
    >
    > Beware of recursion though! If that happens, you need to create unique
    > names for your functions, but as you know these beforehand I don't see
    > any problem with that - just enumerate them, like f1, f2, f3....
    >
    > Diez


    In other words:

    >>> d = {}
    >>>
    >>> # don't use str, that is the name of the built-in string type
    >>> text = '''

    .... def f(state):
    .... print state
    .... return True
    .... '''
    >>>
    >>> exec text in d
    >>>
    >>> f('state')

    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    NameError: name 'f' is not defined
    >>>
    >>> f = d['f']
    >>> f('state')

    state
    True


    Matt
    Matimus, Apr 30, 2008
    #3
  4. Thanks All!

    you've solved my problem.

    D
    Danny Shevitz, Apr 30, 2008
    #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. Reporter
    Replies:
    3
    Views:
    470
    Mike Schilling
    May 12, 2007
  2. John Dalberg
    Replies:
    1
    Views:
    151
    Ray Costanzo [MVP]
    Sep 24, 2004
  3. dale zhang
    Replies:
    8
    Views:
    419
    Tintin
    Nov 30, 2004
  4. Replies:
    1
    Views:
    220
  5. Peng Yu
    Replies:
    2
    Views:
    136
    Tad J McClellan
    Jun 24, 2008
Loading...

Share This Page