2014-06-10 6 views
12

मेरे कोड को डीबग करने में, मैं एक सूची समझ का उपयोग करना चाहता हूं। हालांकि, ऐसा लगता है कि जब मैं किसी फ़ंक्शन के अंदर हूं तो मैं डीबगर से सूची समझ का मूल्यांकन नहीं कर सकता।पायथन डीबगर से सूची समझ स्कोप त्रुटि

मैं पायथन 3.4 का उपयोग कर रहा हूं।

स्क्रिप्ट सामग्री:

$ cat test.py 
#!/usr/bin/python 

def foo(): 
    x = [1, 2, 3, 3, 4] 

    print(x) 

foo() 

इंटरएक्टिव डिबगिंग:

$ python3 -mpdb test.py                                   
> /tmp/test.py(3)<module>() 
-> def foo(): 
(Pdb) step 
> /tmp/test.py(8)<module>() 
-> foo() 
(Pdb) 
--Call-- 
> /tmp/test.py(3)foo() 
-> def foo(): 
(Pdb) 
> /tmp/test.py(4)foo() 
-> x = [1, 2, 3, 3, 4] 
(Pdb) 
> /tmp/test.py(6)foo() 
-> print(x) 
(Pdb) p [x for _ in range(1)] 
*** NameError: name 'x' is not defined 
(Pdb) p x 
[1, 2, 3, 3, 4] 

क्यों x सूची समझ के लिए अज्ञात है? मैं डीबगर से सूची समझ का मूल्यांकन कैसे कर सकता हूं, या समकक्ष व्यवहार प्राप्त कर सकता हूं? क्या यह एक बग है, या यह डीबगर के लिए मौलिक सीमा का कुछ प्रकार है?

+0

@ वीड्राक हू, मुझे बस एक छोटी टेस्ट स्क्रिप्ट में एहसास हुआ, कि यह काम करता है। मैं कुछ खुदाई करूँगा और एक छोटी दौड़ने योग्य लिपि के साथ वापस आऊंगा! – gerrit

+1

@Veedrac ने इसे बिल्कुल जोड़ने के लिए संपादित किया। – gerrit

+0

सरल उदाहरण: 'पी (लैम्ब्डा: एक्स)()' – Veedrac

उत्तर

11

बदलाव के कारण अजगर 3 में, आप pdb में interact आदेश का उपयोग करने के लिए इससे पहले कि आप किसी भी गैर वैश्विक चर का उपयोग कर सकते है जिस तरह से समझ लागू की जाती है।

>>> def foo(): [][0] 
... 
>>> foo() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 1, in foo 
IndexError: list index out of range 
>>> import pdb;pdb.pm() 
> <stdin>(1)foo() 
(Pdb) x = 4 
(Pdb) [x for _ in range(2)] 
*** NameError: name 'x' is not defined 
(Pdb) interact 
*interactive* 
>>> [x for _ in range(2)] 
[4, 4] 
>>> 
7

pdb साथ कोड चल रहा प्रतीत हो रहा है:

eval(compiled_code, globals(), locals()) 

(या शायद सिर्फ eval(string, globals(), locals()))।

दुर्भाग्यवश, संकलन पर पाइथन स्थानीय चर के बारे में नहीं जानता है। यह सामान्य रूप से कोई फर्क नहीं पड़ता:

import dis 
dis.dis(compile("x", "", "eval")) 
#>>> 1   0 LOAD_NAME    0 (x) 
#>>>    3 RETURN_VALUE 

लेकिन जब एक और गुंजाइश ऐसी lambda की एक सूची समझ के साथ के रूप में, शुरू की है, इस बुरी तरह से संकलित:

dis.dis(compile("(lambda: x)()", "", "eval")) 
#>>> 1   0 LOAD_CONST    0 (<code object <lambda> at 0x7fac20708d20, file "", line 1>) 
#>>>    3 LOAD_CONST    1 ('<lambda>') 
#>>>    6 MAKE_FUNCTION   0 
#>>>    9 CALL_FUNCTION   0 (0 positional, 0 keyword pair) 
#>>>    12 RETURN_VALUE 
# The code of the internal lambda 
dis.dis(compile("(lambda: x)()", "", "eval").co_consts[0]) 
#>>> 1   0 LOAD_GLOBAL    0 (x) 
#>>>    3 RETURN_VALUE 

नोट करें कि यह LOAD_GLOBAL है जहां x स्थानीय स्कूली में है पीई।


यहाँ यह चारों ओर पाने के लिए एक पूरी तरह से बेवकूफ हैक है:

(Pdb) eval("(lambda: x)()", vars()) 
[1, 2, 3, 3, 4] 
+0

आह, और मॉड्यूल-स्तर पर होने पर यह काम करता है, क्योंकि 'x'' स्थानीय() 'में नहीं है। मुझे पहले यह नहीं मिला। – gerrit

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