打印定义lambda函数的代码[复制]

时间:2022-11-19 11:52:23

This question already has an answer here:

这个问题已经有了答案:

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

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

Example if I define this function through the lambda syntax:

如果我通过lambda语法定义这个函数:

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

I'd like to get this output:

我想要得到这个输出:

x==2

6 个解决方案

#1


55  

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

只要将代码保存到源文件中,就可以使用inspect模块检索对象的源代码。

example: open editor type:

例子:打开编辑器类型:

myfunction = lambda x: x==2

save as lamtest.py

另存为lamtest.py

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

打开shell类型的python,以获得交互式python类型:

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

the result:

结果:

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

#2


18  

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

它只适用于基于数学的操作,但您可能会看到“症状”的Lambda()对象。它的设计正是为了这个目的:

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

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

#3


10  

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.

虽然我通常同意检查是一个很好的答案,但是我不同意您不能获得解释器中定义的对象的源代码。如果你使用dill.source。来自dill的getsource,您可以获得函数和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


6  

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.

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

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

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

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

这两个对象(lambda_func和def_func)在python中是等效的。事实上,如果您使用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

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

在这种情况下,您可以看到,当一个关系多到一个时,获得原始代码是多么困难。

#5


1  

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

#6


-1  

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.

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

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

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.

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

#1


55  

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

只要将代码保存到源文件中,就可以使用inspect模块检索对象的源代码。

example: open editor type:

例子:打开编辑器类型:

myfunction = lambda x: x==2

save as lamtest.py

另存为lamtest.py

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

打开shell类型的python,以获得交互式python类型:

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

the result:

结果:

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

#2


18  

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

它只适用于基于数学的操作,但您可能会看到“症状”的Lambda()对象。它的设计正是为了这个目的:

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

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

#3


10  

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.

虽然我通常同意检查是一个很好的答案,但是我不同意您不能获得解释器中定义的对象的源代码。如果你使用dill.source。来自dill的getsource,您可以获得函数和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


6  

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.

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

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

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

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

这两个对象(lambda_func和def_func)在python中是等效的。事实上,如果您使用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

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

在这种情况下,您可以看到,当一个关系多到一个时,获得原始代码是多么困难。

#5


1  

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

#6


-1  

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.

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

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

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.

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