1

If I define a function

def foo(function):
    import inspect
    return inspect.getsource(function)

and then call it, I get:

In [11]: foo(lambda x: x[0] + x[1]*2)
Out[11]: 'foo(lambda x: x[0] + x[1]*2)\n'

Note how it printed the entire line, rather than just the lambda function.

Is there a way to get it to output just the lambda?

Desired output:

In [11]: foo(lambda x: x[0] + x[1]*2)
lambda x: x[0] + x[1]*2'

Is there a way to do this that doesn't involve using a regular expression?

EDIT:

Example of how ast.parse(inspect.getsource(function)) may fail:

ast.parse(foo(
    lambda x: x+1))
ignoring_gravity
  • 6,677
  • 4
  • 32
  • 65

1 Answers1

0

inspect.getsource will return a string that not only includes the source code of the object that is being inspected, but also the full call trace of the function that the object is being passed to. For example:

def foo(function):
   import inspect
   return inspect.getsource(function)

val = foo(lambda x: x[0] + x[1]*2)

Will result in the string 'val = foo(lambda x: x[0] + x[1]*2)\n' stored under val.

To more accurately pull the source of function in the string returned from inspect.getsource(function), you can use the ast module, returning for the function source code by anchoring a search on the foo object name:

def foo(function):
   import inspect, ast
   src = inspect.getsource(function) #store function's source, including the call trace
   return [ast.unparse(i.args[0]) for i in ast.walk(ast.parse(src)) #parse the src string 
           if isinstance(i, ast.Call) and i.func.id == 'foo'][0] #find a call AST node where the name of the object is 'foo'

print(foo(lambda x: x[0] + x[1]*2))

Output:

'lambda x: x[0] + x[1] * 2'
Ajax1234
  • 69,937
  • 8
  • 61
  • 102