Я хотел бы иметь возможность распечатать код определения лямбда-функции.
Пример, если я определяю эту функцию с помощью синтаксиса лямбда:
>>>myfunction = lambda x: x==2
>>>print_code(myfunction)
Я хочу получить этот вывод:
x==2
Я хотел бы иметь возможность распечатать код определения лямбда-функции.
Пример, если я определяю эту функцию с помощью синтаксиса лямбда:
>>>myfunction = lambda x: x==2
>>>print_code(myfunction)
Я хочу получить этот вывод:
x==2
Пока вы сохраняете свой код в исходном файле, вы можете получить исходный код объект с использованием проверяющего модуля.
Пример: открытый тип редактора:
myfunction = lambda x: x==2
сохранить как lamtest.py
открыть оболочку типа python, чтобы перейти к интерактивному python введите следующее:
>>>from lamtest import myfunc
>>>import inspect
>>>inspect.getsource(myfunc)
результат:
'myfunc = lambda x: x==2\n'
Он будет работать только для математических операций, но вы можете посмотреть 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. Хотя я обычно соглашаюсь с тем, что 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
>>>
Это будет очень сложно, потому что ваша лямбда-функция будет скомпилирована в байт-код, а ваш объект 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
В этом случае вы можете увидеть, как было бы сложно получить исходный код, когда это отношение "много к одному"
Как это?
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() больше подходит для вашей проблемы. Он встроен, а затем вы можете использовать строки для передачи кода в своем коде.