Python 打印定义lambda函数的代码

Python 打印定义lambda函数的代码,python,Python,我希望能够打印lambda函数的定义代码 示例:如果我通过lambda语法定义此函数: >>>myfunction = lambda x: x==2 >>>print_code(myfunction) 我希望得到以下输出: x==2 你为什么要这样做 我想您可以使用“dis”模块将代码分解为python字节码,但这可能不是您想要的 同样,我看不到这个用例。也许eval()更适合您的问题。它是内置的,然后您可以使用字符串在代码中传递代码 这将非常困难,因为

我希望能够打印lambda函数的定义代码

示例:如果我通过lambda语法定义此函数:

>>>myfunction = lambda x: x==2
>>>print_code(myfunction)
我希望得到以下输出:

x==2

你为什么要这样做

我想您可以使用“dis”模块将代码分解为python字节码,但这可能不是您想要的


同样,我看不到这个用例。也许eval()更适合您的问题。它是内置的,然后您可以使用字符串在代码中传递代码

这将非常困难,因为lambda函数将被编译为字节码,而myfunction对象将只指向字节码,而不是您编写的可读代码

例如,如果定义两个函数,一个使用lambda语法,另一个使用def语句,如下所示:

>>> lambda_func = lambda x: x==2
>>> def def_func(x): return x == 2
...
就python而言,这两个对象(lambda_func和def_func)是等价的。事实上,如果您继续使用(如rebra建议的)拆解它们,您将得到相同的结果:

>>> 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
在这种情况下,您可以看到,如果是多对一关系,那么获取原始代码是多么困难

这是怎么回事

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
只要将代码保存到源文件,就可以检索的源代码 使用inspect模块的对象

例如: 打开编辑器类型:

myfunction = lambda x: x==2
另存为lamtest.py

打开shell类型的python以访问交互式python 键入以下内容:

>>>from lamtest import myfunc
>>>import inspect
>>>inspect.getsource(myfunc)
结果是:

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

它只适用于基于数学的操作,但您可以查看的是的
Lambda()
对象。它的设计正是为了这个目的:

>>> from sympy import *
>>> x = Symbol('x')
>>> l = Lambda(x, x**2)
>>> l
Lambda(_x, _x**2)
>>> l(3)
9
它甚至支持漂亮的打印:

>>> pprint(l)
 ⎛    2⎞
Λ⎝x, x ⎠
要执行equals示例,请使用SymPy Eq()对象:

它支持部分参数扩展:

>>> y = Symbol('y')
>>> l2 = Lambda((x, y), x*y + x)
>>> l2(1)
Lambda(_y, 1 + _y)
>>> l2(1, 2)
3
当然,你还可以获得SymPy所有的计算机代数:

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

顺便说一下,如果这听起来像一个无耻的插头,那是因为它是。我是Symphy的开发者之一

虽然我大体上同意
inspect
是一个很好的答案,但我不同意您无法获得解释器中定义的对象的源代码。如果使用
dill.source.getsource
from,则可以获取函数和lambda的源代码,即使它们是以交互方式定义的。 它还可以从curries中定义的绑定或未绑定类方法和函数中获取的代码。。。但是,如果没有封闭对象的代码,您可能无法编译该代码

>>> 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

>>> 


请使用
def x(args)
而不是
x=lambda(args)
。这不能回答您的问题,但请使用def。由于此帖子标记为重复,因此无法再发布答案。但是,重复post涉及的是普通函数,而不是lambda。我在这里发布了一个特定于lambdas的答案:我发现更容易将所需函数捕获为字符串,然后在lambda函数中对其求值,例如,其中f是定义函数:map(lambda x:eval(f),x)的字符串。这样,函数被定义一次,但仍然可以作为文本。对于那些有足够的堆栈溢出特权的人,考虑投票来重新打开这个问题。调用标准的
inspect.getsourcelines()
函数来内省标准可调用项的源代码,该函数无法返回定义lambda的行的确切子字符串,而是返回整行。这很少是任何人想要的。换句话说,这个问题不是重复的,不应该被关闭。“再诅咒你一次,@MartijnPieters@CecilCurry听起来是个不错的答案,因为另一个问题就是解决这个问题的。那里已经有了答案,完全涵盖了我已经建立了一个状态机。从一种状态到另一种状态的条件由lambda函数定义。我想画一个状态机图,每个弧上都有lambda函数。遗憾的是python反编译器的状态很差,另一个用例是一种增强的自动文档形式——lambda有时用作函数/方法中的默认值(例如排序等)。当记录函数/方法签名时,自动文档编制人员能够列出lamda源代码将非常有用。我对这个答案投了反对票,因为我个人觉得答案不应该以“为什么要这样做?”开头。与pcn的解决方案相比,这在控制台中有效,即使您删除了源代码。唯一的缺点是你需要把代码放在一个字符串中…@Mapad:这不是缺点。如果不修改Python编译器将源代码保存在docstring中,这是满足您需求的唯一方法。您知道为什么它不能在Python shell中工作吗?它不能在shell中工作,因为代码没有在文件中定义。inspect查看文件属性,打开该文件并读取它。@MartinVilcans是的!您甚至可以飞行:terminal-->python[enter]import antigravity:)这很酷,不幸的是,如果lambda不是从真实文件生成的,它就不起作用。例如,如果您从字符串或控制台使用它,它会引发“IOError:无法获取源代码”。这并不能完全回答问题。有没有办法只获取
x==2
而不是声明的完整源代码?sympy是一款令人惊叹的软件,不使用它是无耻的!非常感谢:)请注意,如果函数不一定是面向数学的或是简单的,
mini_lambda
提供了一个轻单变量替代SymPy:此模块似乎不适用于Jupyter笔记本,仅供参考-请参阅。
>>> 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

>>>