python - sintaxis - imprime el código que define una función lambda
lambda python 3 español (6)
Esta pregunta ya tiene una respuesta aquí:
Me gustaría poder imprimir el código de definición de una función lambda.
Ejemplo si defino esta función a través de la sintaxis lambda:
>>>myfunction = lambda x: x==2
>>>print_code(myfunction)
Me gustaría obtener esta salida:
x==2
¿Cómo es esto?
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
¿Por qué quieres hacer esto?
Supongo que podrías usar el módulo "dis" para desensamblar tu código en bytecode de python, pero probablemente no sea lo que deseas.
http://www.python.org/doc/2.5.2/lib/module-dis.html
De nuevo, no puedo ver el caso de uso para esto. Tal vez eval () es más adecuado para su problema. Está integrado, y luego puede usar cadenas para pasar el código en su código.
Siempre que guarde su código en un archivo fuente , puede recuperar el código fuente de un objeto utilizando el módulo de inspección.
ejemplo: tipo de editor abierto:
myfunction = lambda x: x==2
guardar como lamtest.py
abrir shell tipo python para obtener python interactivo escriba lo siguiente:
>>>from lamtest import myfunc
>>>import inspect
>>>inspect.getsource(myfunc)
el resultado:
''myfunc = lambda x: x==2/n''
Solo funcionará para operaciones basadas en matemática, pero puede mirar el objeto Lambda()
SymPy . Fue diseñado exactamente para este propósito:
>>> from sympy import *
>>> x = Symbol(''x'')
>>> l = Lambda(x, x**2)
>>> l
Lambda(_x, _x**2)
>>> l(3)
9
Incluso admite impresión bonita:
>>> pprint(l)
⎛ 2⎞
Λ⎝x, x ⎠
Para hacer el ejemplo de igualdad, use el objeto SymPy Eq ():
>>> l1 = Lambda(x, Eq(x, 2))
>>> l1
Lambda(_x, _x == 2)
>>> l1(2)
True
Es compatible con la expansión parcial de argumentos:
>>> y = Symbol(''y'')
>>> l2 = Lambda((x, y), x*y + x)
>>> l2(1)
Lambda(_y, 1 + _y)
>>> l2(1, 2)
3
Y, por supuesto, tiene la ventaja de obtener todo el álgebra computacional de SymPy:
>>> l3 = Lambda(x, sin(x*pi/3))
>>> pprint(l3(1))
⎽⎽⎽
╲╱ 3
─────
2
Por cierto, si esto suena como un enchufe desvergonzado, es porque lo es. Soy uno de los desarrolladores de SymPy.
Aunque generalmente estoy de acuerdo en que inspect
es una buena respuesta, no estoy de acuerdo con que no se pueda obtener el código fuente de los objetos definidos en el intérprete. Si usa dill.source.getsource
de dill
, puede obtener el origen de las funciones y lambdas, incluso si están definidas interactivamente. También puede obtener el código de métodos y funciones de clase enlazados o no definidos definidos en curries ... sin embargo, es posible que no pueda compilar ese código sin el código del objeto adjunto.
>>> 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
>>>
Eso será muy difícil, porque su función lambda se compilará en bytecode, y su objeto myfunction solo estará apuntando al bytecode y no al código legible por humanos que usted escribió.
Por ejemplo, si define 2 funciones, una con sintaxis lambda y otra con una declaración def, de la siguiente manera:
>>> lambda_func = lambda x: x==2
>>> def def_func(x): return x == 2
...
Estos 2 objetos (lambda_func y def_func) serán equivalentes en lo que se refiere a python. De hecho, si continúa y los desensambla utilizando el módulo dis (como se sugirió en rebra), obtendrá resultados idénticos:
>>> 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
Siendo ese el caso, puede ver cómo sería difícil obtener el código original cuando se trata de una relación muchos a uno