2016-11-16 12 views
12

द्वारा पाइथन अभिव्यक्ति मूल्यांकन चरण का पता लगाने के लिए मैं पाइथन अभिव्यक्ति मूल्यांकन विज़ुअलाइज़र लिखने की कोशिश कर रहा हूं, जो दिखाएगा कि पाइथन अभिव्यक्तियों का मूल्यांकन चरण-दर-चरण (शिक्षा उद्देश्यों के लिए) कैसे किया जाता है। फिलिप गुओ का पायथन ट्यूटर बहुत अच्छा है, लेकिन यह लाइन द्वारा पायथन प्रोग्राम लाइन का मूल्यांकन करता है, और मैंने पाया कि छात्रों को कभी-कभी यह समझ में नहीं आता कि sorted([4, 2, 3, 1] + [5, 6])[1] == 2 जैसे एक-पंक्ति अभिव्यक्ति का मूल्यांकन कैसे किया जाता है और मैं इस प्रक्रिया को विज़ुअलाइज़ करना चाहता हूं। (ऐसा लगता है कि कोई भी अभी तक यह किया - कम से कम मैं कुछ नहीं मिला।) आदर्श समाधान इस तरह तार के एक दृश्य पैदा करेगा:चरण

sorted([4, 2, 3, 1] + [5, 6])[1] == 2 
sorted(>> [4, 2, 3, 1] + [5, 6] <<)[1] == 2 
>> sorted([4, 2, 3, 1, 5, 6]) << [1] == 2 
>> [1 2 3 4 5 6][1] << == 2 
>> 2 == 2 << 
True 

यहाँ >> और << अभिव्यक्ति है कि का एक हिस्सा उजागर करने के लिए उपयोग किया जाता है वर्तमान चरण पर मूल्यांकन किया और फिर इसके मूल्य से बदल दिया। eval(compile(node, '', 'eval')) साथ यह मूल्यांकन (हो सकता है, मैं बाद में एनीमेशन के कुछ प्रकार के लिए इस क्रम में परिवर्तित करने की कोशिश करेंगे।)

मेरे वर्तमान रणनीति ast.parse() उपयोग करने के लिए एएसटी में स्ट्रिंग पार्स करने में है, तो एक नोड है कि पहले का मूल्यांकन किया जाएगा लगता है, (मैं निश्चित रूप से पूरे पायथन को पुन: कार्यान्वित नहीं करना चाहता हूं :)), एएसटी नोड में मूल्यांकन के परिणाम को परिवर्तित करें (repr और फिर ast.parse()?) और परिणाम नोड के साथ वर्तमान नोड को प्रतिस्थापित करें, फिर संशोधित कोड स्ट्रिंग का उत्पादन करने के लिए codegen.to_source का उपयोग करें (संशोधित) एएसटी से और उसी प्रक्रिया को जारी रखें जब तक कि मेरे पास पेड़ में केवल एक अक्षर नहीं है।

मेरा प्रश्न है: मैं एक नोड कैसे ढूंढ सकता हूं जिसका मूल्यांकन पहले किया जाएगा? ऐसा लगता है कि मैं वृक्ष गहराई को पार कर सकता हूं- पहले ast.NodeVisitor उप-वर्ग के साथ, लेकिन मुझे यकीन नहीं है कि मैं कैसे पता लगा सकता हूं कि मैं वांछित नोड तक पहुंचा और इसके बाद मैं ट्रैवर्सिंग कैसे रोक सकता हूं?


संपादित करें।

यह संभव है कि पेड़ के परिवर्तन के साथ मेरा प्रारंभिक दृष्टिकोण संभव नहीं है। वास्तव में, पाइथन अभिव्यक्ति के मूल्यांकन का एक प्रारंभिक कदम कुछ उप-अभिव्यक्ति को एक सरल (जैसे अंकगणित में) के प्रतिस्थापन होना आवश्यक नहीं है। उदाहरण के लिए, सूची की समझ एक और अधिक जटिल व्यवहार प्रदान करती है जिसे शब्दों में व्यक्त नहीं किया जा सकता है, इस बात को उस चीज़ से प्रतिस्थापित करें, फिर रिकर्सिव दोहराएं। तो मैं थोड़ा सवाल फिर से शुरू करता हूं। मुझे प्रोग्रामेटिकल रूप से कुछ तरीके की ज़रूरत है कि कैसे पाइथन अभिव्यक्तियों का मूल्यांकन चरण-दर-चरण किया जाता है। उदाहरण के लिए, मैक्रोपी की tracing सुविधा, जो कि जेसनहरपर द्वारा उल्लिखित है, इस चरण में स्वीकार्य समाधान है। दुर्भाग्यवश, मैक्रोपी को त्याग दिया प्रतीत होता है और पाइथन 3 के साथ काम नहीं करता है। क्या कोई विचार है कि पाइथन 3 में पूर्ण मैक्रोपी पोर्ट किए बिना इस ट्रेसिंग व्यवहार को कैसे दिखाना है?


EDIT2।

इस बक्षीस से सम्मानित होने के बाद, मुझे similar question और debugger बहुत नज़दीकी सुविधाओं के साथ मिला। हालांकि, क्योंकि उस प्रश्न के लिए कोई अंतिम जवाब नहीं है, और मुझे पूर्ण डीबगर की आवश्यकता नहीं है, मैं अभी भी एक ऐसे उत्तर की तलाश कर रहा हूं जिसका उपयोग उदाहरण के लिए जुपीटर पर्यावरण में किया जा सके।

उत्तर

6

अभिव्यक्ति स्टेपिंग Thonny IDE में कार्यान्वित किया जाता: एक वैकल्पिक पद्धति चरणों एक-एक करके IPython में दिखाने के लिए हो सकता है।

यह एएसटी उपकरण का उपयोग करता है, जहां प्रत्येक (उप) अभिव्यक्ति eafter(before(<location info>), e) में परिवर्तित हो जाती है। कार्य before और after अतिरिक्त कॉल कॉल करने के लिए डमी फ़ंक्शन हैं-पायथन के ट्रेसिंग सिस्टम में। ये अतिरिक्त कॉल सूचित करते हैं जब (उप) अभिव्यक्ति मूल्यांकन शुरू होने वाला है या अभी समाप्त हो गया है। (प्रत्येक कथन की शुरुआत और अंत का पता लगाने के लिए इसी प्रकार के डमी फ़ंक्शन जोड़े जाते हैं।)

एएसटी उपकरण और इन नई घटनाओं की व्याख्या thonny.backend.FancyTracer में की गई है।

पायथन के एएसटी नोड्स में संबंधित टेक्स्ट श्रेणियों की प्रारंभिक स्थिति होती है, लेकिन वे कभी-कभी गलत होती हैं। अंत स्थिति पूरी तरह गायब हैं। thonny.ast_utils.mark_text_ranges इस पर ध्यान देने की कोशिश करता है (लेकिन इस समय समाधान अपूर्ण है)।

यह अच्छा होगा अगर किसी ने Thonny से अधिक सामान्य पैकेज में प्रासंगिक कार्यक्षमता निकाली। शायद दो पैकेज भी - पायथन एएसटी के लिए स्थान जानकारी की गणना करने के लिए और अन्य पायथन कोड के विस्तृत ट्रेसिंग के लिए। अगर कोई नेतृत्व करता है तो मैं इससे मदद करने के लिए तैयार रहूंगा।

1

दो सूचियों के अतिरिक्त निश्चित रूप से उस कोड में मूल्यांकन करने वाला पहला नोड नहीं है; मेरा मानना ​​है कि नौ पहले नोड मूल्यांकन वास्तव में देखते हैं - sorted, 4, 2, 3, 1, [4,2,3,1], 5, 6, [5,6]। न केवल आपको यह निर्धारित करना होगा कि किस क्रम मूल्यांकन का प्रदर्शन किया जाता है, आपको यह भी तय करना होगा कि इनमें से कौन से मूल्यांकन दिखाए जा रहे हैं।

मुझे लगता है कि आपकी समस्या का बेहतर दृष्टिकोण एएसटी नोड्स को संशोधित करना होगा ताकि वे निष्पादित होने के दुष्प्रभाव के रूप में राज्य के पहले/बाद में उत्सर्जित हो जाएं। आप उनके आदेश की परवाह नहीं करेंगे, आप बस एक बार पूरी अभिव्यक्ति निष्पादित करेंगे। और पहले से ही macropy नामक एक पैकेज है जिसमें एक ट्रेसिंग सुविधा है जो वास्तव में यह करती है। इसका आउटपुट काफी कुछ नहीं है जिसे आप पूछ रहे हैं, लेकिन इसे शायद एक करीबी मैच के रूप में संशोधित किया जा सकता है।

+0

एचएम-एम, 'मैक्रॉपी' [ट्रेसिंग] (https://github.com/lihaoyi/macropy#tracing) बहुत करीब और आशाजनक दिखता है, धन्यवाद। मुझे इसमें खोदना होगा। –

+0

हां, 'मैक्रोपी' पायथन 3 :( –

2

dis मॉड्यूल का उपयोग क्यों नहीं करें?

चूंकि सीपीथन पाइथन को बाइटकोड से संकलित करता है और इसे चलाता है, बाइटकोड को देखते हुए आपको वास्तव में क्या होता है इसका सबसे अच्छा विचार देता है।

In [1]: import dis 

In [2]: dis.dis('sorted([4, 2, 3, 1] + [5, 6])[1] == 2') 
    1   0 LOAD_NAME    0 (sorted) 
       3 LOAD_CONST    0 (4) 
       6 LOAD_CONST    1 (2) 
       9 LOAD_CONST    2 (3) 
      12 LOAD_CONST    3 (1) 
      15 BUILD_LIST    4 
      18 LOAD_CONST    4 (5) 
      21 LOAD_CONST    5 (6) 
      24 BUILD_LIST    2 
      27 BINARY_ADD 
      28 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
      31 LOAD_CONST    3 (1) 
      34 BINARY_SUBSCR 
      35 LOAD_CONST    1 (2) 
      38 COMPARE_OP    2 (==) 
      41 RETURN_VALUE 

संपादित:

In [1]: [4, 2, 3, 1] 
Out[1]: [4, 2, 3, 1] 

In [2]: [4, 2, 3, 1] + [5, 6] 
Out[2]: [4, 2, 3, 1, 5, 6] 

In [3]: sorted([4, 2, 3, 1, 5, 6]) 
Out[3]: [1, 2, 3, 4, 5, 6] 

In [4]: [1, 2, 3, 4, 5, 6][1] 
Out[4]: 2 

In [5]: 2 == 2 
Out[5]: True 
+0

तकनीकी रूप से काम नहीं करता है, यह सही है। हालांकि, मेरे प्रश्न का उद्देश्य एक ऐसा टूल बनाना है जो मुझे पाइथन में अपने पहले चरण के दौरान छात्रों को सिखाने में मदद करेगा, जब वे सिर्फ सॉफ्टवेयर प्रोग्रामिंग की बुनियादी अवधारणाओं से परिचित हो जाएं। और यह कंप्यूटर विज्ञान के छात्र नहीं हैं, पाइथन उनके लिए एक उपकरण है, न कि वैज्ञानिक हितों का एक वस्तु। इसलिए उन्हें बाइटकोड को प्रश्न के उत्तर के रूप में दिखाना असंभव है * क्या हो रहा है यहां? * शायद, उस बाइटकोड को सुलभ शर्तों में प्रक्रिया को पुनर्निर्माण के लिए किसी भी तरह से पार्स करना संभव है, लेकिन यह आसान नहीं लगता है। –

+0

@ IlyaV.Schurov चूंकि आप छात्रों को "पहला कदम" पढ़ रहे हैं पायथन, क्यों "कवर ऑफ ले लो" बिल्कुल? और चूंकि मैं एक मैकेनिकल इंजीनियर हूं जो पाइथन को एक उपकरण के रूप में उपयोग करता है, मुझे लगता है कि मैं कह सकता हूं कि यह संभव है कि गैर कंप्यूटर-वैज्ञानिकों के लिए यह संभव है कि पाथ कैसे काम पर :-) –

+0

निश्चित रूप से यह संभव है। मैं न तो एक कंप्यूटर वैज्ञानिक :) लेकिन मुझे नहीं लगता कि हमें शुरुआत में इसकी ज़रूरत है। यह थोड़ा सा है "इससे पहले कि आप फेसबुक पर लॉगिन कर सकें, आपको आर्किटेक्चर x86, असेंबली, सी, टीसीपी/आईपी प्रोटोकॉल, HTTP प्रोटोकॉल, एचटीएमएल, सीएसएस और जावास्क्रिप्ट का अध्ययन करना होगा। फिर अपनी तस्वीरों को पोस्ट करें। ओह, रुको, हम जेपीईजी के बारे में भूल गए "।Anywayay, विचार के लिए धन्यवाद, यह अच्छा है। –

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