print the code which defined a lambda function

Python

Python Problem Overview


I'd like to be able to print the definition code of a lambda function.

Example if I define this function through the lambda syntax:

>>>myfunction = lambda x: x==2
>>>print_code(myfunction)

I'd like to get this output:

x==2

Python Solutions


Solution 1 - Python

As long as you save your code to a source file you can retrieve the source code of an object using the inspect module.

example: open editor type:

myfunction = lambda x: x==2

save as lamtest.py

open shell type python to get to interactive python type the following:

>>>from lamtest import myfunc
>>>import inspect
>>>inspect.getsource(myfunc)

the result:

'myfunc = lambda x: x==2\n'

Solution 2 - Python

It will only work for mathematical based operations, but you might look at SymPy's Lambda() object. It was designed exactly for this purpose:

>>> from sympy import *
>>> x = Symbol('x')
>>> l = Lambda(x, x**2)
>>> l
Lambda(_x, _x**2)
>>> l(3)
9

It even supports pretty printing:

>>> pprint(l)
 ⎛    2⎞
Λ⎝x, x ⎠

To do your equals example, us the SymPy Eq() object:

>>> l1 = Lambda(x, Eq(x, 2))
>>> l1
Lambda(_x, _x == 2)
>>> l1(2)
True

It supports partial argument expansion:

>>> y = Symbol('y')
>>> l2 = Lambda((x, y), x*y + x)
>>> l2(1)
Lambda(_y, 1 + _y)
>>> l2(1, 2)
3

And of course, you get the advantage of getting all of SymPy's computer algebra:

>>> l3 = Lambda(x, sin(x*pi/3))
>>> pprint(l3(1))
  ⎽⎽⎽
╲╱ 3 
─────
  2  

By the way, if this sounds like a shameless plug, it's because it is. I am one of the developers of SymPy.

Solution 3 - Python

While I'd generally agree that inspect is a good answer, I'd disagree that you can't get the source code of objects defined in the interpreter. If you use dill.source.getsource from dill, you can get the source of functions and lambdas, even if they are defined interactively. It also can get the code for from bound or unbound class methods and functions defined in curries... however, you might not be able to compile that code without the enclosing object's code.

>>> from dill.source import getsource
>>> 
>>> def add(x,y):
...   return x+y
... 
>>> squared = lambda x:x**2
>>> 
>>> print getsource(add)
def add(x,y):
  return x+y

>>> print getsource(squared)
squared = lambda x:x**2

>>> 
>>> class Foo(object):
...   def bar(self, x):
...     return x*x+x
... 
>>> f = Foo()
>>> 
>>> print getsource(f.bar)
def bar(self, x):
    return x*x+x

>>> 

Solution 4 - Python

That will be very difficult, because your lambda function will be compiled to bytecode, and your myfunction object will only be pointing to the bytecode and not the human-readable code that you wrote.

For example, if you define 2 functions, one using lambda syntax and one using a def statement, as follows:

>>> lambda_func = lambda x: x==2
>>> def def_func(x): return x == 2
...

These 2 objects (lambda_func and def_func) will be equivalent as far as python is concerned. In fact, if you go ahead and disassemble them using the dis module (as rebra suggested), you will get identical results:

>>> import dis
>>> dis.dis(lambda_func)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE
>>> dis.dis(def_func)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               2 (==)
              9 RETURN_VALUE

That being the case, you can see how it would be difficult to obtain the original code when it's a many to one relationship

Solution 5 - Python

How's this?

class MyLambda( object ):
    def __init__( self, body ):
        self.body= body
    def __call__( self, arg ):
        x = arg
        return eval( self.body )
    def __str__( self ):
        return self.body

f= MyLambda( "x == 2" )
print f(1)
print f(2)
print f

Solution 6 - Python

Why do you want to do this?

I guess you could use the "dis" module to disassemble your code to python bytecode, but it's probably not what you want.

http://www.python.org/doc/2.5.2/lib/module-dis.html

Again, I can't see the use case for this. Perhaps eval() is more suited for your problem. It is built in, and then you can use strings to pass code around in your code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMapadView Question on Stackoverflow
Solution 1 - PythonpcnView Answer on Stackoverflow
Solution 2 - PythonasmeurerView Answer on Stackoverflow
Solution 3 - PythonMike McKernsView Answer on Stackoverflow
Solution 4 - PythonMoeView Answer on Stackoverflow
Solution 5 - PythonS.LottView Answer on Stackoverflow
Solution 6 - PythonrebraView Answer on Stackoverflow