Распечатать код, который определяет лямбда-функцию

Я хотел бы иметь возможность распечатать код определения лямбда-функции.

Пример, если я определяю эту функцию с помощью синтаксиса лямбда:

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

Я хочу получить этот вывод:

x==2

Ответ 1

Пока вы сохраняете свой код в исходном файле, вы можете получить исходный код объект с использованием проверяющего модуля.

Пример: открытый тип редактора:

myfunction = lambda x: x==2

сохранить как lamtest.py

открыть оболочку типа python, чтобы перейти к интерактивному python введите следующее:

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

результат:

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

Ответ 2

Он будет работать только для математических операций, но вы можете посмотреть 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

Хотя я обычно соглашаюсь с тем, что inspect является хорошим ответом, я бы не согласился с тем, что вы не можете получить исходный код объектов, определенных в интерпретаторе. Если вы используете dill.source.getsource из dill, вы можете получить источник функций и лямбда, даже если они определены в интерактивном режиме. Он также может получить код для связанных или несвязанных методов и функций класса, определенных в карри... однако вы не сможете скомпилировать этот код без прилагаемого объектного кода.

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

Это будет очень сложно, потому что ваша лямбда-функция будет скомпилирована в байт-код, а ваш объект myfunction будет указывать только на байт-код, а не на человеко-читаемый код, который вы написали.

Например, если вы определяете 2 функции, используя синтаксис лямбда и один с помощью инструкции def, следующим образом:

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

Эти 2 объекта (lambda_func и def_func) будут эквивалентны по отношению к python. На самом деле, если вы продолжите и разбираете их, используя dis module (как рекомендовал ребра), вы получите одинаковые результаты:

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

В этом случае вы можете увидеть, как было бы сложно получить исходный код, когда это отношение "много к одному"

Ответ 5

Как это?

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

Почему вы хотите это сделать?

Я думаю, вы могли бы использовать модуль "dis", чтобы разобрать свой код на байт-код python, но он, вероятно, не тот, который вы хотите.

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

Опять же, я не вижу примера использования для этого. Возможно, eval() больше подходит для вашей проблемы. Он встроен, а затем вы можете использовать строки для передачи кода в своем коде.