Velocity Reviews > how to convert a multiline string to an anonymous function?

# how to convert a multiline string to an anonymous function?

Danny Shevitz
Guest
Posts: n/a

 04-29-2008
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

Diez B. Roggisch
Guest
Posts: n/a

 04-29-2008
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

Matimus
Guest
Posts: n/a

 04-30-2008
On Apr 29, 3:39 pm, "Diez B. Roggisch" <(E-Mail Removed)> 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

Danny Shevitz
Guest
Posts: n/a

 04-30-2008
Thanks All!

you've solved my problem.

D

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Edward A. Falk C Programming 1 04-04-2013 08:07 PM Reporter Java 3 05-12-2007 05:23 AM noeldamonmiller@gmail.com Perl Misc 1 02-10-2005 01:08 AM dale zhang Perl Misc 8 11-30-2004 06:53 AM John Dalberg ASP General 1 09-24-2004 07:27 PM

Advertisments