当前位置:  开发笔记 > 编程语言 > 正文

打印定义lambda函数的代码

如何解决《打印定义lambda函数的代码》经验,为你挑选了4个好方法。

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

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

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

我想得到这个输出:

x==2

小智.. 64

只要将代码保存到源文件,就可以使用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'

它在shell中不起作用,因为代码没有在文件中定义,inspect查看__file__属性并打开该文件并读取它. (6认同)

任何想法为什么它不能在python shell中工作? (4认同)


asmeurer.. 21

它只适用于基于数学的操作,但您可以查看SymPy的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 ?

要做你的等于示例,我们使用SymPy Eq()对象:

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

它支持部分参数扩展:

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

顺便说一句,如果这听起来像一个无耻的插头,那是因为它是.我是SymPy的开发人员之一.



1> 小智..:

只要将代码保存到源文件,就可以使用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'


它在shell中不起作用,因为代码没有在文件中定义,inspect查看__file__属性并打开该文件并读取它.
任何想法为什么它不能在python shell中工作?

2> asmeurer..:

它只适用于基于数学的操作,但您可以查看SymPy的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 ?

要做你的等于示例,我们使用SymPy Eq()对象:

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

它支持部分参数扩展:

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

顺便说一句,如果这听起来像一个无耻的插头,那是因为它是.我是SymPy的开发人员之一.



3> Mike McKerns..:

虽然我一般都认为这inspect是一个很好的答案,但我不同意你无法获得解释器中定义的对象的源代码.如果使用dill.source.getsourcefrom dill,则可以获取函数和lambdas的来源,即使它们是以交互方式定义的.它还可以从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

>>> 



4> Moe..:

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

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

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

就python而言,这两个对象(lambda_func和def_func)将是等效的.事实上,如果你继续使用dis模块进行反汇编(如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

在这种情况下,你可以看到当它是多对一关系时如何获得原始代码是很困难的

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有