2015-03-03 2 views
7

चलो कहते हैं कि मैं निम्नलिखित बहु लाइन स्ट्रिंग करते हैं:कैसे पायथन में कार्यकारी या execfile से किसी त्रुटि के लाइन नंबर पाने के लिए

cmd = """ 
    a = 1 + 1 
    b = [ 
     2 + 2, 
     4 + 4, 
    ] 
    bork bork bork 
""" 

और मैं किसी खास दायरे में यह निष्पादित करने के लिए करना चाहते हैं:

scope = {} 
exec(cmd, scope) 
print scope[ 'b' ] 

कमांड के लाइन 6 पर SyntaxError है, और मैं उपयोगकर्ता को इसकी रिपोर्ट करने में सक्षम होना चाहता हूं। मैं लाइन नंबर कैसे प्राप्त करूं? मैं इस की कोशिश की है:

try: 
    exec(cmd, scope) # <-- let's say this is on line 123 of the source file 
except Exception, err: 
    a, b, c = sys.exc_info() 
    line_number = c.tb_lineno # <-- this gets me 123, not 6 
    print "%s at line %d (%s)" % (a, line_number, b.message) 

... लेकिन मैं exec बयान के लाइन नंबर, नहीं बहु लाइन आदेश के भीतर लाइन नंबर मिलता है।

अद्यतन: यह इस उदाहरण के लिए मनमाने ढंग से चुने गए अपवाद के प्रकार को संभालने का पता चला है, SyntaxError, किसी अन्य प्रकार के हैंडलिंग से अलग है। स्पष्टीकरण के लिए, मैं एक समाधान देख रहा हूं जो किसी भी प्रकार के अपवाद के साथ copes।

+0

आप में देखा है [ 'pdb'] (https://docs.python.org/2/library/pdb.html)? – jonrsharpe

उत्तर

7

वाक्यविन्यास त्रुटियों के लिए, में संग्रहीत आपके मामले में, स्रोत लाइन संख्या अपवाद ऑब्जेक्ट पर lineno ध्वज के रूप में उपलब्ध है। यह वाक्यविन्यास त्रुटियों के लिए विशिष्ट होता है, जहां लाइन नंबर त्रुटि के अभिन्न अंग है:

>>> cmd = """ 
... 1 \ + 
... 2 * " 
... """ 
>>> try: 
... exec cmd 
... except SyntaxError as err: 
... print err.lineno 
... 
2 

आप भी अन्य त्रुटियों को संभाल चाहते हैं, एक नया except ब्लॉक except Exception, err जोड़ सकते हैं और लाइन की गणना करने के traceback मॉड्यूल का उपयोग रनटाइम त्रुटि के लिए संख्या।

import sys 
import traceback 

class InterpreterError(Exception): pass 

def my_exec(cmd, globals=None, locals=None, description='source string'): 
    try: 
     exec(cmd, globals, locals) 
    except SyntaxError as err: 
     error_class = err.__class__.__name__ 
     detail = err.args[0] 
     line_number = err.lineno 
    except Exception as err: 
     error_class = err.__class__.__name__ 
     detail = err.args[0] 
     cl, exc, tb = sys.exc_info() 
     line_number = traceback.extract_tb(tb)[-1][1] 
    else: 
     return 
    raise InterpreterError("%s at line %d of %s: %s" % (error_class, line_number, description, detail)) 

उदाहरण:

>>> my_exec("1+1") # no exception 
>>> 
>>> my_exec("1+1\nbork") 
... 
InterpreterError: NameError at line 2 of source string: name 'bork' is not defined 
>>> 
>>> my_exec("1+1\nbork bork bork") 
... 
InterpreterError: SyntaxError at line 2 of source string: invalid syntax 
>>> 
>>> my_exec("1+1\n'''") 
... 
InterpreterError: SyntaxError at line 2 of source string: EOF while scanning triple-quoted string 
+0

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

+1

@jez आम तौर पर संपादन फिक्स के लिए आरक्षित होते हैं, न कि उत्तर में बड़े हस्तक्षेप के लिए। मैं कम से कम पीईपी 8 का पालन करने वाला कोड बनाउंगा। संभावित कारण यह है कि 'सिंटेक्स एरर' अलग क्यों है, यह कोड को चलाने का मौका मिलने से पहले संकलक से आता है। अन्य त्रुटियां रन-टाइम इंजन से आती हैं और रेखा संख्या को ट्रेसबैक के रूप में निकाला जाना चाहिए। आप इसे एक स्थिर भाषा में एक संकलन-समय और रन-टाइम त्रुटि के बीच के अंतर की तरह सोच सकते हैं - वे अलग हैं क्योंकि वे बहुत अलग तंत्र और विभिन्न समय से उठाए जाते हैं। – user4815162342

+0

सभी गिनती पर ध्यान दिया। आम तौर पर मैं पेप 8 के चेहरे पर हँसता हूं लेकिन मुझे लगता है कि आपकी जगह आपके नियम हैं। और अगर आप इसे अनुचित मानते हैं तो निश्चित रूप से इसे हटाएं- मैं सिर्फ आपके उत्तर को स्वीकार करना चाहता था क्योंकि यह मुझे समाधान के लिए प्रेरित करता था, और स्वीकार्य उत्तर को पूरा समाधान रखने के लिए चाहता था (अपने स्वयं के उत्तर लिखने के लिए आपके सुझाए गए दृष्टिकोण का उपयोग करने में गलत लगता है मैं फिर स्वीकार करता हूं) – jez

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