打印定义一个lambda函数的代码
我希望能够打印一个lambda函数的定义代码。
例如,如果我通过lambda语法来定义这个函数:
>>>myfunction = lambda x: x==2 >>>print_code(myfunction)
我想要得到这个输出:
x==2
只要将代码保存到源文件中 ,就可以使用inspect模块检索对象的源代码。
例如:打开编辑器types:
myfunction = lambda x: x==2
保存为lamtest.py
打开shelltypes的python得到交互式的pythontypes如下:
>>>from lamtest import myfunc >>>import inspect >>>inspect.getsource(myfunc)
结果:
'myfunc = lambda x: x==2\n'
它只适用于基于math的操作,但是您可以看看SymPy的Lambda()
对象。 它的devise正是为了这个目的:
>>> 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的开发人员之一。
虽然我通常会同意inspect
是一个很好的答案,但我不同意你不能得到解释器中定义的对象的源代码。 如果您使用dill.source.getsource
,即使它们是交互式定义的,您也可以获得函数和lambdaexpression式的来源。 它也可以从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 >>>
这将是非常困难的,因为你的lambda函数将被编译为字节码,而你的myfunction对象只会指向字节码,而不是你编写的人类可读代码。
例如,如果您定义了2个函数,一个使用lambda语法,一个使用def语句,如下所示:
>>> lambda_func = lambda x: x==2 >>> def def_func(x): return x == 2 ...
就python而言,这两个对象(lambda_func和def_func)将是等效的。 事实上,如果您继续使用dis模块进行反汇编(如rebrabuild议),您将得到相同的结果:
>>> 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
你为什么要这样做?
我想你可以使用“dis”模块来反汇编你的代码到python字节码,但它可能不是你想要的。
http://www.python.org/doc/2.5.2/lib/module-dis.html
再一次,我不能看到这个用例。 也许eval()更适合你的问题。 它是内置的,然后你可以使用string在代码中传递代码。