अजगर डीबगर स्वचालित रूप से त्रुटि पर शुरू करना


216

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


12
क्या आपने स्वीकार किए गए उत्तर को बदलने पर विचार किया है?
जोस्ट

जवाबों:


127

आप अपवाद ट्रेसबैक प्रिंट करने के लिए ट्रेसबैक.प्रिंट_एक्ससीसी का उपयोग कर सकते हैं । फिर ट्रेसबैक निकालने के लिए sys.exc_info का उपयोग करें और अंत में उस ट्रेसबैक के साथ pdb.post_mortem पर कॉल करें।

import pdb, traceback, sys

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        extype, value, tb = sys.exc_info()
        traceback.print_exc()
        pdb.post_mortem(tb)

यदि आप उस फ्रेम के स्थानीय लोगों का उपयोग करके code.interact के साथ एक इंटरेक्टिव कमांड लाइन शुरू करना चाहते हैं , जहां अपवाद उत्पन्न हो सकता है

import traceback, sys, code

def bombs():
    a = []
    print a[0]

if __name__ == '__main__':
    try:
        bombs()
    except:
        type, value, tb = sys.exc_info()
        traceback.print_exc()
        last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb
        frame = last_frame().tb_frame
        ns = dict(frame.f_globals)
        ns.update(frame.f_locals)
        code.interact(local=ns)

पहला समाधान आगे अजगर रसोई की किताब
dirkjot

3
क्यों किसी को भी पसंद करेंगे codeसे अधिक pdbबाद पूर्व पर विस्तार करने के लिए लगता है के बाद से?
K3 --- rnc

मेरा भी यही सवाल है? आप क्यों पसंद करेंगे code?
एआरएच

2
फिर sys.exc_infoट्रेसबैक निकालने के लिए उपयोग करें और अंत pdb.post_mortemमें उस ट्रेसबैक के साथ कॉल करें । आपको ट्रेसबैक ऑब्जेक्ट को पास करने की आवश्यकता नहीं है pdb.post_mortem। से डॉक्स : कोई ट्रैस बैक दिया जाता है, तो यह अपवाद है कि वर्तमान में संभाला जा रहा है (यदि डिफ़ॉल्ट इस्तेमाल किया जा रहा है एक अपवाद संभाला जा रहा किया जाना चाहिए) में से एक का उपयोग करता है।
पायोत्र दोब्रोगोस्ट

2
@PiotrDobrogost अच्छी बात है। मुझे लगता है कि यह जानना अधिक उपयोगी है कि आप एक tb ऑब्जेक्ट को पास कर सकते हैं, हालांकि, चूंकि यह एपीआई को बेहतर ढंग से प्रदर्शित करता है। दोनों विकल्पों को जानने के लिए अच्छा है।
दाविडा

454
python -m pdb -c continue myscript.py

यदि आप -c continueध्वज प्रदान नहीं करते हैं, तो निष्पादन शुरू होने पर आपको 'सी' (जारी रखने के लिए) दर्ज करना होगा। फिर यह एरर पॉइंट पर चलेगा और आपको वहां कंट्रोल देगा। जैसा कि ezzx द्वारा बताया गया है , यह ध्वज पायथन 3.2 में एक नया जोड़ है, इसलिए पहले के पायथन संस्करणों के लिए 'c' दर्ज करना आवश्यक है (देखें https://docs.python.org/3/library/pdb.html )।


5
" एन 'सी' " का उल्लेख करने के लिए धन्यवाद - मैं आमतौर पर 'आर' ("रन" के लिए) दर्ज करता था, इससे इसका उपयोग किया जा रहा है gdb; और जब आप 'आर' दर्ज करते हैं pdb, तो प्रोग्राम वास्तव में चलता है, लेकिन त्रुटि पर बंद नहीं होता है (और न ही बैकट्रेस उत्पन्न करता है); जब तक मैंने इसे नहीं पढ़ा, मुझे आश्चर्य हुआ। चीयर्स!
सदाउ

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

40
कृपया ओपी, इसे उत्तर के रूप में स्वीकार करें। यह सबसे उपयोगी है और मैंने दूसरे को पढ़ने में 5 मिनट बर्बाद किए हैं जब तक कि मैंने इसे एक हिट नहीं किया ... यह पहले होना चाहिए!
जेगेदस

4
यह भी उसी के साथ काम करता है ipdb; और निश्चित रूप से तर्कों को स्क्रिप्ट के बाद जोड़ा जा सकता है!
टूटूजाजु

20
यह पायथन 2.7 के साथ काम नहीं करता है। docs.python.org/3/library/pdb.html : "संस्करण 3.2 में नया: pdb.py अब एक -c विकल्प स्वीकार करता है जो कमांड निष्पादित करता है"
eqzx

68

निम्न मॉड्यूल का उपयोग करें:

import sys

def info(type, value, tb):
    if hasattr(sys, 'ps1') or not sys.stderr.isatty():
    # we are in interactive mode or we don't have a tty-like
    # device, so we call the default hook
        sys.__excepthook__(type, value, tb)
    else:
        import traceback, pdb
        # we are NOT in interactive mode, print the exception...
        traceback.print_exception(type, value, tb)
        print
        # ...then start the debugger in post-mortem mode.
        # pdb.pm() # deprecated
        pdb.post_mortem(tb) # more "modern"

sys.excepthook = info

नाम दें debug (या जो भी आपको पसंद है) और इसे अपने अजगर मार्ग में कहीं रख दें।

अब, अपनी स्क्रिप्ट की शुरुआत में, बस एक जोड़ें import debug


2
यह स्वीकृत उत्तर होना चाहिए - इसमें मौजूदा कोड के किसी भी संशोधन की आवश्यकता नहीं है या हर चीज को लपेटने की जरूरत है, try-catchजो कि बदसूरत आईएमओ है।
सीपर

मैं इस उत्तर को बार-बार पसंद करता हूं, लेकिन pudbअधिक पसंद करता हूं pdb। कॉपी-एंड-पेस्ट पर लौटें, जो निश्चित रूप से मेरे जीवन में आदेश की कमी के बारे में कुछ कहता है।
Stabledog

47

Ipython के पास इस व्यवहार को शुरू करने के लिए एक कमांड है: % pdb । यह वही है जो आपने वर्णित किया है, शायद थोड़ा और भी (सिंटैक्स हाइलाइटिंग और कोड पूरा होने के साथ आपको अधिक जानकारीपूर्ण बैकट्रैक दे रहा है)। यह निश्चित रूप से एक कोशिश के काबिल है!


3
और इस के लिए केवल उचित जवाब है।
माइकल


4
ध्यान दें कि - जैसा कि डॉक्स @ ताम्रथिश् लिंक में भी उल्लेख किया गया है - %debugकिसी को त्रुटि का सामना करने के बाद डीबगर को खोलने की अनुमति देता है । मैं अक्सर इसे पसंद करता हूं %pdb। (व्यापार बंद केवल टाइपिंग है qहर बार जब आप किसी त्रुटि को डिबग नहीं करना चाहते हैं, तो हर बार जब आप किसी त्रुटि को डीबग करना चाहते %debugहैं तो टाइपिंग करें ।)
ब्रहम स्नाइडर

1
यह भी ध्यान रखें कि हर सत्र के लिए अपने आप c.InteractiveShell.pdb = Trueमें सेटिंग ipython_config.pyचालू हो जाती है %pdb
ब्रह्म स्नाइडर

33

यह डिबगर नहीं है, लेकिन शायद उतना ही उपयोगी है (?)

मुझे पता है कि मैंने एक भाषण में गुइडो का उल्लेख किया।

मैंने अभी-अभी अजगर की जाँच की है? - और यदि आप -i कमांड का उपयोग करते हैं तो आप बातचीत कर सकते हैं कि आपकी स्क्रिप्ट कहाँ रुकी है।

इसलिए यह स्क्रिप्ट दी गई है:

testlist = [1,2,3,4,5, 0]

prev_i = None
for i in testlist:
    if not prev_i:
        prev_i = i
    else:
        result = prev_i/i

आप यह आउटपुट प्राप्त कर सकते हैं!

PS D:\> python -i debugtest.py
Traceback (most recent call last):
  File "debugtest.py", line 10, in <module>
    result = prev_i/i
ZeroDivisionError: integer division or modulo by zero
>>>
>>>
>>> prev_i
1
>>> i
0
>>>

सच कहूं तो मैंने इसका उपयोग नहीं किया है, लेकिन मुझे ऐसा करना चाहिए, बहुत उपयोगी लगता है।


हल्के, लेकिन अक्सर बस क्या जरूरत है
Casebash

8
लगभग उतना उपयोगी नहीं है, वैश्विक दायरे में लॉन्च होता है। जो भी कार्य दुर्घटनाग्रस्त हो गया, उसके आसपास प्रहार नहीं कर सकते।
24

21

IPython कमांड लाइन पर इसे सरल बनाता है:

python myscript.py arg1 arg2

के लिए फिर से लिखा जा सकता है

ipython --pdb myscript.py -- arg1 arg2

या, इसी तरह, अगर एक मॉड्यूल को बुला रहा है:

python -m mymodule arg1 arg2

के लिए फिर से लिखा जा सकता है

ipython --pdb -m mymodule -- arg1 arg2

--IPython को स्क्रिप्ट के तर्कों को पढ़ने से रोकने के लिए ध्यान दें ।

यह भी pdb के बजाय बढ़ाया IPython डीबगर (ipdb) को लागू करने का लाभ है।


9

यदि आप उपयोग कर रहे हैं ipython, तो लॉन्चिंग प्रकार के बाद%pdb

In [1]: %pdb
Automatic pdb calling has been turned ON

उदाहरण के लिए
बृहस्पति

6

यदि आप IPython वातावरण का उपयोग कर रहे हैं, तो आप बस% डिबग का उपयोग कर सकते हैं और शेल आपको निरीक्षण आदि के लिए ipdb वातावरण के साथ आक्रामक रेखा पर वापस ले जाएगा। जैसा कि ऊपर बताया गया एक और विकल्प iPython Magic% ddb का उपयोग करना है जो प्रभावी रूप से करता है। वही।


ध्यान दें कि यदि मॉड्यूल फ़ंक्शन में त्रुटि हुई है, तो आप फ़्रेम के माध्यम से नेविगेट कर सकते हैं upऔर downअपने कोड की लाइन पर वापस जाने के लिए कमांड कर सकते हैं जिसने त्रुटि उत्पन्न की।
जीन पॉल

4

आप इस लाइन को अपने कोड में डाल सकते हैं:

import pdb ; pdb.set_trace()

अधिक जानकारी: किसी भी पंक्ति में अजगर डीबगर प्रारंभ करें


8
यह कोड को रोकता है और उस पंक्ति में एक डीबगर शुरू करता है जहां आपने यह कमांड लगाई है, न कि उस लाइन पर जहां एक अपवाद घटित हुआ है
BlueFast

3

शुरुआत में टाइप सी के बिना इसे चलाने के लिए:

python -m pdb -c c <script name>

Pdb की अपनी कमांड लाइन दलीलें हैं: -cc निष्पादन की शुरुआत में c (ontinue) कमांड निष्पादित करेगा और प्रोग्राम तब तक निर्बाध रूप से चलेगा जब तक कि त्रुटि न हो जाए।


3

python2.7 प्रेस में python -m pdb script.py जारी रहता है और यह एरर के लिए चलेगा और डिबग के लिए वहां टूट जाएगा।


1

यदि आप एक मॉड्यूल चला रहे हैं:

python -m mymodule

और अब आप प्रवेश करना चाहते हैं pdbजब कोई अपवाद होता है, तो यह करें:

PYTHONPATH="." python -m pdb -c c mymodule/__main__.py

(या अपने विस्तारPYTHONPATH )। PYTHONPATHजरूरत इस बात की है कि मॉड्यूल पथ में पाया जाता है, क्योंकि आप pdbअभी मॉड्यूल चला रहे हैं।


0

पदानुक्रम में सर्वोच्च अपवाद वर्ग के निर्माता के अंदर एक विराम बिंदु रखें, और अधिकांश बार आप देखेंगे कि त्रुटि कहाँ पर उठाया गया था।

ब्रेकपॉइंट लगाने का मतलब है कि आप जो भी चाहते हैं उसका मतलब है: आप आईडीई, या pdb.set_trace, या जो भी उपयोग कर सकते हैं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.