2008-12-02 29 views
36

Bir lambda işlevinin tanımlama kodunu yazdırabilmeyi istiyorum.bir lambda işlevi tanımlayan kodu yazdır

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

bu çıktıyı almak istiyorum:

Örnek

Ben lambda sözdizimi aracılığıyla bu işlevi tanımlarsanız

x==2 
+1

Lütfen x = lambda (args) 'yerine' def x (args) 'kullanın. Bu sorunuza cevap vermiyor, ancak lütfen bunun için def 'leri kullanın. –

cevap

54

Sürece bir kaynak dosyasına kodu kaydetmek olarak incelemek modülü kullanarak bir nesne kaynak kodunu alabilirsiniz.

örnek: açık editör türü:

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

sonucu:

myfunction = lambda x: x==2 

lamtest.py olarak

açık kabuk tipi piton kaydet aşağıdaki interaktif piton tipine almak :

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

Python kabuğunda neden çalışmaz diye bir fikriniz var mı? – noamtm

+6

kabukta çalışmaz, çünkü kod bir dosyada tanımlanmadı, __file__ niteliğine bakarak inceler ve dosyayı açar ve okur. – Moe

+0

IPython'da çalışıyor, nice –

-1

Bunu neden istiyorsun?

Sana piton baytkoduna kodunuzu sökmeye "dis" modülünü kullanabilirsiniz sanırım, ama ne istediğinizi muhtemelen değil.

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

Yine, bunun için kullanım örneğini göremez. Belki de eval() probleminiz için daha uygundur. İçinde yerleşiktir ve kodunuzdaki kodu geçirmek için dizeleri kullanabilirsiniz.

+0

Bir durum makinesi oluşturdum. Bir durumdan diğerine geçme koşulları, lambda işlevleri tarafından tanımlanır. Her bir yayın üstündeki lambda fonksiyonları ile bu durum makinesinin bir grafiğini çizmek istedim. – Mapad

+0

Ne yazık ki python parça bozucular oldukça zayıf durumda, orada <= 2,5 tane var. –

+0

Başka bir kullanım durumu gelişmiş otomatik belgelerin bir biçimidir - Lambda bazen işlev/yöntemde varsayılan değerler olarak kullanılır (örneğin, vb.). İşlev/yöntem imzası belgelendiğinde lamda kaynak kodunu listeleyebilmek için otomatik bir dokümantasyon için yararlı olacaktır. –

6

Bu çok zor olacaktır çünkü lambda işleviniz bytecode olarak derlenecek ve işlev nesneniz yalnızca yazdığınız insan tarafından okunabilir kod değil baytkodu işaret edecektir. Eğer bir def ifadesini kullanarak lambda sözdizimi ve birini kullanarak 2 fonksiyonları birini tanımlarsanız

Örneğin, aşağıdaki gibi:

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

Bu 2 nesneler (lambda_func ve def_func) kadarıyla piton olduğu gibi eşdeğer olacak endişeli.

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

durumda olmak, bunu orijinal kodunu almak için zor olacağını nasıl görebilirsiniz Yani: Aslında, eğer devam edin ve dis module (rebra önerdiği gibi), alacağınız aynı sonuçları kullanarak onları sökmeye Bu bir çok ilişki var olduğunda

1

Bu nasıl?

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

PCn'den gelen çözümle karşılaştırıldığında, kaynak kodu silmiş olsanız bile bu konsolda çalışır. Bunun tek dezavantajı, kodu bir dizeye koymanız gerektiğidir ... – Mapad

+0

@Mapad: Olumsuz değil. İhtiyaçlarınızı karşılamak için Python derleyicisini bir dokümanda kaynak kaydetmek için değiştirmeden tek yol. –

18

Yalnızca matematik tabanlı işlemler için çalışır, ancak SymPy adlı kullanıcının Lambda() nesnesine bakabilirsiniz.Tam olarak bu amaç için tasarlanmış:

>>> pprint(l) 
⎛ 2⎞ 
Λ⎝x, x ⎠ 

senin örneğini eşittir yapmak için, bize SymPy Eşitlik() nesnesi:

>>> from sympy import * 
>>> x = Symbol('x') 
>>> l = Lambda(x, x**2) 
>>> l 
Lambda(_x, _x**2) 
>>> l(3) 
9 

Hatta oldukça yazdırmayı destekler

>>> l1 = Lambda(x, Eq(x, 2)) 
>>> l1 
Lambda(_x, _x == 2) 
>>> l1(2) 
True 

O kısmi bağımsız genişletmeyi destekler:

>>> y = Symbol('y') 
>>> l2 = Lambda((x, y), x*y + x) 
>>> l2(1) 
Lambda(_y, 1 + _y) 
>>> l2(1, 2) 
3 

Ve tabii ki, sen SymPy bilgisayar cebir tüm almanın avantajı elde edersiniz:

>>> l3 = Lambda(x, sin(x*pi/3)) 
>>> pprint(l3(1)) 
    ⎽⎽⎽ 
╲╱ 3 
───── 
    2 

arada, bu utanmaz fiş gibi geliyor eğer, bunun nedeni bu. SymPy'nin geliştiricilerinden biriyim.

+0

sympy, kullanımı zor olmayan utanç verici bir yazılım parçası! çok teşekkür ederim :) –

8

Genel olarak inspect'un iyi bir yanıt olduğunu kabul edersem de, yorumlayıcıda tanımlı olan nesnelerin kaynak kodunu alamadığınızı kabul etmem. dill'dan dill.source.getsource kullanırsanız, etkileşimli olarak tanımlanmış olsa bile, işlevlerin kaynağı ve lambdas alabilirsiniz. Ayrıca, körüklerde tanımlanan ciltli veya bağlı olmayan sınıf yöntemleri ve işlevleri için kod da alabilirsiniz ... ancak, bu kodu, örtülü nesnenin kodu olmadan derleyemeyebilirsiniz.

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

>>> 
İlgili konular