You might find the following handy, for creating simple "one-liner"
functions on the fly:
from string import find
def func( f ):
i = find( f, ':' )
if i < 0:
raise ValueError, 'need colon in function string ' + `f`
args, body = f[:i], f[i+1:]
f = 'def f(' + args + '): return ' + body
bad = 1 # guilty until proven innocent
try:
exec( f ) # creates local func 'f'
bad = 0
finally:
if bad:
print 'Error in func: couldn\'t exec ' + `f`
return f
This takes a string of the form
[arglist] ':' expression
as its argument, and returns the function defined by
'def f(' arglist '): return ' expression
The name 'f' is local to the invocation of 'func', so effectively
vanishes when 'func' returns (the binding of the _name_ 'f' to the
function object vanishes, but the function object itself does not); so
from the point of view of the caller, the function returned by 'func' is
anonymous (cannot interfere with name bindings in the caller, or indeed
even be invoked by name).
For example, given function
def map( f, x ):
y = []
for e in x:
y.append( f(e) )
return y
we have
>>> map( func('x: x*x'), range(8) )
[0, 1, 4, 9, 16, 25, 36, 49]
>>>
Or
>>> flist = map( func, ['x:x+x', 'y:y*y', 'z:42'] )
>>> for f in flist:
... print f(3)
...
6
9
42
>>>
I often find 'func' to be handy, in conjunction with LISPish functions
like 'map', when doing interactive data crunching.
> You could almost do it with exec(), I'd think, except that exec()
> doesn't return its value.
Right, that's why the exec is packaged inside a function here.
> Are multi-line expressions even allowed?
The context ("allowed" where?) wasn't clear to me. exec will crunch any
legit Python program text, and it's certainly possible to generalize
'func' to allow creating anonymous functions built out of arbitrary
Python code. But note that representing complex functions as strings
gets clumsy, because you have to get the newlines, and the right amount
of leading indentation, in the right places (or, define an un-Python-like
string representation, and program a fancier 'func' to translate that
into legit Python before handing it to 'exec').
the-function-that-is-named-is-not-the-true-function-ly y'rs - tim
Tim Peters tim@ksr.com
not speaking for Kendall Square Research Corp