2008-12-02 15 views
36

परिभाषित कोड मुद्रित करें, मैं एक लैम्ब्डा फ़ंक्शन के परिभाषा कोड को मुद्रित करने में सक्षम होना चाहता हूं।एक लैम्ब्डा फ़ंक्शन

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

मैं इस उत्पादन प्राप्त करना चाहते हैं:

उदाहरण अगर मैं लैम्ब्डा वाक्य रचना के माध्यम से इस समारोह को परिभाषित

x==2 
+1

कृपया 'x = lambda (args)' के बजाय 'def x (args)' का उपयोग करें। यह आपके प्रश्न का उत्तर नहीं देता है, लेकिन इसके लिए डीईएफ का उपयोग करें। –

उत्तर

54

जब तक आप एक स्रोत फ़ाइल के लिए अपने कोड को बचाने के रूप में आप के स्रोत कोड एक वस्तु का निरीक्षण मॉड्यूल का उपयोग कर प्राप्त कर सकते हैं।

उदाहरण: खुला संपादक के प्रकार:

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

परिणाम:

myfunction = lambda x: x==2 

बचाने lamtest.py रूप

खुला खोल प्रकार अजगर निम्नलिखित इंटरैक्टिव अजगर प्रकार को पाने के लिए :

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

कोई विचार है कि यह पाइथन खोल में क्यों काम नहीं कर सकता है? – noamtm

+6

यह खोल में काम नहीं करता है क्योंकि कोड को फ़ाइल में परिभाषित नहीं किया गया है, निरीक्षण __file__ विशेषता को देखता है और उस फ़ाइल को खोलता है और इसे पढ़ता है। – Moe

+0

आईपीथॉन में काम करता है, अच्छा –

-1

क्यों आप ऐसा करना चाहते हैं?

मैं तुम्हें "जिले" अजगर बाईटकोड के लिए अपने कोड डिसअसेंबल करने का मॉड्यूल इस्तेमाल कर सकते हैं लगता है, लेकिन यह शायद आप क्या चाहते हैं नहीं है।

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

फिर से, मैं इस के लिए उपयोग के मामले नहीं देख सकता। शायद eval() आपकी समस्या के लिए अधिक उपयुक्त है। यह बनाया गया है, और फिर आप अपने कोड में कोड पास करने के लिए तारों का उपयोग कर सकते हैं।

+0

मैंने एक राज्य मशीन बनाई है। एक राज्य से दूसरे राज्य में जाने की स्थितियों को लैम्ब्डा कार्यों द्वारा परिभाषित किया जाता है। मैं प्रत्येक चाप के शीर्ष पर लैम्ब्डा कार्यों के साथ, इस राज्य मशीन का एक ग्राफ प्लॉट करना चाहता था। – Mapad

+0

अफसोस की तरह पाइथन decompilers बल्कि गरीब राज्य में हैं, वहाँ <= 2.5 के लिए एक है। –

+0

एक और उपयोग केस उन्नत स्वचालित दस्तावेज का एक रूप होगा - लैम्ब्डा को कभी-कभी कार्यों/विधियों (उदाहरण के लिए आदि) में डिफ़ॉल्ट मान के रूप में उपयोग किया जाता है। फ़ंक्शन/विधि हस्ताक्षर को दस्तावेज करते समय स्वचालित दस्तावेज़कर्ता के लिए लैम्डा स्रोत कोड सूचीबद्ध करने में सक्षम होना उपयोगी होगा। –

6

यह बहुत मुश्किल होगा, क्योंकि आपका लैम्ब्डा फ़ंक्शन बाइटकोड में संकलित किया जाएगा, और आपका माईफंक्शन ऑब्जेक्ट केवल बाइटकोड को इंगित करेगा, न कि आपके द्वारा लिखे गए मानव-पठनीय कोड।

उदाहरण के लिए, यदि आप, 2 काम करता है, एक लैम्ब्डा वाक्यविन्यास और एक का उपयोग कर एक डीईएफ़ कथन का उपयोग को परिभाषित इस प्रकार है:

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

इन 2 वस्तुओं (lambda_func और def_func) जहाँ तक अजगर के रूप में बराबर होगी चिंतित। वास्तव में, यदि आप आगे बढ़ कर dis module (के रूप में 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 

मामले जा रहा है, आप देख सकते हैं कि कैसे यह मूल कोड प्राप्त करने के लिए मुश्किल होगा जब यह एक रिश्ता

1

इस कैसा है करने के लिए एक बहुत है?

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

पीसीएन से समाधान की तुलना में, यह कंसोल में काम करता है, भले ही आपने सोर्स कोड हटा दिया हो। इसका एकमात्र नकारात्मक पक्ष यह है कि आपको कोड को स्ट्रिंग में रखना होगा ... – Mapad

+0

@Mapad: नकारात्मक नहीं। एक डॉकस्ट्रिंग में स्रोत को बचाने के लिए पाइथन कंपाइलर को मॉडेड किए बिना आपकी आवश्यकता को पूरा करने का एकमात्र तरीका। –

18

यह केवल गणितीय आधारित कार्यों के लिए काम करेंगे, लेकिन आप SymPy के Lambda() वस्तु को देखने के हो सकता है।यह बिल्कुल इस उद्देश्य के लिए डिजाइन किया गया था:

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

अपने उदाहरण के बराबर होती है करने के लिए, हमें SymPy Eq() वस्तु:

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

यह भी सुंदर मुद्रण का समर्थन करता है

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

, अगर यह एक बेशर्म प्लग की तरह लगता है, यह है क्योंकि यह है। मैं सिम्पी के डेवलपर्स में से एक हूं।

+0

सिम्पी सोफवेयर का एक अद्भुत टुकड़ा है, इसका उपयोग न करने के लिए लापरवाह! आपका बहुत बहुत धन्यवाद :) –

8

जबकि मैं आम तौर पर सहमत हूं कि inspect एक अच्छा जवाब है, मैं असहमत हूं कि आपको दुभाषिया में परिभाषित वस्तुओं का स्रोत कोड नहीं मिल सकता है। यदि आप dill से dill.source.getsource का उपयोग करते हैं, तो आप फ़ंक्शंस और लैम्बडास का स्रोत प्राप्त कर सकते हैं, भले ही उन्हें इंटरैक्टिव रूप से परिभाषित किया गया हो। यह सीमाओं में परिभाषित बाध्य या अनबाउंड क्लास विधियों और कार्यों से भी कोड प्राप्त कर सकता है ... हालांकि, हो सकता है कि आप उस कोड को संलग्न ऑब्जेक्ट के कोड के बिना संकलित करने में सक्षम न हों।

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

>>> 
संबंधित मुद्दे