पायथन में अपवाद संदेश को ठीक से कैसे प्राप्त करें


104

पायथन में मानक पुस्तकालय के घटकों से अपवाद के संदेश प्राप्त करने का सबसे अच्छा तरीका क्या है?

मैंने देखा कि कुछ मामलों में आप इसे messageइस तरह से फ़ील्ड के माध्यम से प्राप्त कर सकते हैं :

try:
  pass
except Exception as ex:
  print(ex.message)

लेकिन कुछ मामलों में (उदाहरण के लिए, सॉकेट त्रुटियों के मामले में) आपको कुछ इस तरह करना होगा:

try:
  pass
except socket.error as ex:
  print(ex)

मुझे आश्चर्य है कि इनमें से अधिकांश स्थितियों को कवर करने का कोई मानक तरीका है?


1
आप दो अलग-अलग चीजों का सामना कर रहे हैं - except Foo as bar:जैसे ही है except Foo, bar:(पूर्व को छोड़कर नया है, और 3.x में काम करना जारी रखेगा), त्रुटि एक messageविशेषता के साथ आती है या नहीं अलग है।
jonrsharpe

1
@FrozenHeart क्या आप पूछ रहे हैं कि .messageकिसी त्रुटि के लिए पहुँच मानक तरीका है या नहीं?
आनंद एस कुमार

आपके दूसरे उदाहरण के print(msg)लिए बस एक शॉर्टकट हैprint(str(msg))
Salo

@ आनंद एस कुमार येप। क्या यह किसी भी मामले में काम करेगा?
फ्रोजनहार्ट

5
मेरा मानना ​​है कि अभिगमन messageमें कमी है।
जोनाथन रेनहार्ट

जवाबों:


102

यदि आप अंतर्निहित त्रुटियों के लिए प्रलेखन को देखते हैं , तो आप देखेंगे कि अधिकांश Exceptionवर्ग एक messageविशेषता के रूप में अपना पहला तर्क देते हैं। हालांकि ये सभी नहीं करते हैं।

विशेष रूप से, EnvironmentError(उपवर्गों के साथ IOErrorऔर OSError) के एक पहला तर्क है errno, की दूसरी strerror। वहाँ कोई नहीं है message... strerrorक्या सामान्य रूप से होगा एक मोटे तौर पर अनुरूप है message

अधिक आम तौर पर, उप-वर्ग Exceptionवे जो चाहें कर सकते हैं। उनके पास messageविशेषता हो भी सकती है और नहीं भी । भविष्य में निर्मित Exceptionएस में एक messageविशेषता नहीं हो सकती है । Exceptionतृतीय-पक्ष लाइब्रेरी या उपयोगकर्ता कोड से आयात किए गए किसी भी उपवर्ग में messageविशेषता नहीं हो सकती है ।

मुझे लगता है कि इसे संभालने का उचित तरीका उन विशिष्ट Exceptionउपवर्गों की पहचान करना है जिन्हें आप पकड़ना चाहते हैं, और फिर उन सब के बजाय केवल एक को पकड़ते हैं, फिर उन except Exceptionविशिष्ट विशेषताओं का उपयोग करें जो विशिष्ट उपवर्ग परिभाषित करता है जो आप चाहते हैं।

यदि आपको printकुछ करना चाहिए , तो मुझे लगता है कि पकड़े गए को Exceptionस्वयं प्रिंट करना सबसे अधिक संभावना है कि आप क्या चाहते हैं, इसकी कोई messageविशेषता है या नहीं।

आप संदेश विशेषता के लिए जाँच कर सकते हैं यदि आप इस तरह चाहते थे, लेकिन मैं वास्तव में इसका सुझाव नहीं दूंगा क्योंकि यह सिर्फ गड़बड़ लगता है:

try:
    pass
except Exception as e:
    # Just print(e) is cleaner and more likely what you want,
    # but if you insist on printing message specifically whenever possible...
    if hasattr(e, 'message'):
        print(e.message)
    else:
        print(e)

जवाब के लिए धन्यवाद। क्या str(ex)इसके बजाय उपयोग करने का कोई विशेष कारण है ex?
फ्रोजनहार्ट

4
@FrozenHeart - print()स्वचालित रूप str()से आपके लिए कॉल करता है। मैन्युअल रूप से इसे स्वयं कॉल करने का कोई कारण नहीं है, हालांकि यह str()एक तार पर कॉल करने के बाद से हानिरहित है क्योंकि यह केवल स्ट्रिंग को वापस कर देगा।
आर्टऑफवर्फ

1
@ArtOfWarfare मुझे लगता है कि str()अगर संदेश टाइप का है तो समस्याएँ हो सकती हैं unicode
kratenko

39

@Artofwarfare द्वारा दिए गए जवाब में सुधार करने के लिए , यहाँ मैं messageविशेषता के लिए जाँच करने और इसे प्रिंट करने या Exceptionऑब्जेक्ट को फॉलबैक के रूप में मुद्रित करने के लिए एक शून्य तरीका मानता हूँ ।

try:
    pass 
except Exception as e:
    print getattr(e, 'message', repr(e))

कॉल reprवैकल्पिक है, लेकिन मुझे कुछ उपयोग मामलों में यह आवश्यक लगता है।


अपडेट # 1:

@MadPhysicist की टिप्पणी के बाद , यहां इस बात का प्रमाण दिया गया है कि कॉल reprआवश्यक क्यों हो सकता है। अपने दुभाषिया में निम्नलिखित कोड चलाने का प्रयास करें:

try:
    raise Exception 
except Exception as e:
    print(getattr(e, 'message', repr(e)))
    print(getattr(e, 'message', str(e)))

अपडेट # 2:

यहाँ पायथन 2.7 और 3.5 के लिए बारीकियों के साथ एक डेमो दिया गया है: https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533


1
getattrयदि अनुरोधित विशेषता में पास की गई वस्तु में कोई अपवाद नहीं है, तो उसे फेंकता है। यदि आप ऐसा कुछ करना चाहते हैं, तो मुझे लगता है कि आपको इसके लिए वैकल्पिक तीसरे तर्क का उपयोग करना चाहिए getattr, जैसे print getattr(e, 'message', e):। मैंने जो किया उससे बेहतर डिबेट। एक और विकल्प होगा print(e.message if hasattr(e, 'message') else e)
ArtOfWarfare

2
आप के strबजाय लगभग निश्चित रूप से करना चाहते हैं repr
मैड फिजिसिस्ट

2
की तुलना में str, reprबस वर्ग नाम जोड़ता है। उपयोग करने के बजाय repr, मैं उपयोग करने का प्रस्ताव दूंगा print('{e.__class__.__name__}: {e}'.format(e=e))। प्रिंट आउटपुट क्लीनर है और खुद को ऊपर उठाने के आउटपुट का पालन करता है।
kadee

1
उपरोक्त के आधार पर, मुझे मेरे लिए सबसे उपयोगी लगा'{e.__class__.__module__}.{e.__class__.__name__}: {e}'
shadi

1
धन्यवाद!! repr(e)अभी के लिए एकमात्र समाधान था जिसने मुझे कुछ विशेष परिस्थितियों में एक त्रुटि पर कम से कम जानकारी को प्रिंट करने में मदद की। repr(e)पैदावार KeyError(0,)(जो कि त्रुटि है), जबकि str(e)या e.messageकेवल 0क्रमशः या कुछ भी नहीं उपज ।
फ्लोरिअन

0

मुझे भी यही समस्या थी। मुझे लगता है कि सबसे अच्छा समाधान log.exception का उपयोग करना है, जो स्वचालित रूप से स्टैक ट्रेस और त्रुटि संदेश को प्रिंट करेगा, जैसे:

try:
    pass
    log.info('Success')
except:
    log.exception('Failed')

2
क्या है log? मैंने सिर्फ import logपायथन 2.7.13 पर कोशिश की और संदेश मिला कि उस नाम के साथ कोई मॉड्यूल नहीं है। क्या यह आपके द्वारा जोड़ा गया कुछ है pipया इसे अजगर के एक नए संस्करण में जोड़ा गया था (मुझे पता है, मुझे पता है, मुझे पायथन 3 को अपडेट करने की आवश्यकता है ... मैं यही करूँगा कि जैसे ही सेंटोस डिफ़ॉल्ट रूप से अजगर 2 के साथ शिपिंग बंद कर देता है ...)
आर्टऑफवर्फ

7
वह शायद अजगर से लॉगिंग मॉड्यूल का उपयोग कर रहा है और फिर लॉग वेरिएबल के रूप में एक लकड़हारे को तुरंत हटा रहा है। import logging\ nlog = logging.getLogger(__name__)
जोसेप्स

0

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

try:
   # do something that may raise an AuthException
except AuthException as ex:
   if ex.args[0] == "Authentication Timeout.":
      # handle timeout
   else:
      # generic handling
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.