2008-11-03 17 views
11

मुझे हाल ही में अप्रत्याशित कुछ काटा गया है।अपवाद क्यों अक्षम हैं?

try : 
    thing.merge(iterable) # this is an iterable so I add it to the list 
except TypeError : 
    thing.append(iterable) # this is not iterable, so I add it 

ठीक है, यह ठीक काम कर रहा था जब तक मैं एक वस्तु अपवाद से इनहेरिट जो जोड़े जाने के लिए चाहिए था पारित कर दिया: मैं ऐसा ही कुछ बनाना चाहते थे।

दुर्भाग्य से, एक अपवाद संभव है। निम्नलिखित कोड को उठाने नहीं करता है किसी भी TypeError:

for x in Exception() : 
    print 1 

किसी को भी पता है क्यों?

उत्तर

11

ध्यान दें कि क्या हो रहा है निहित स्ट्रिंग रूपांतरण आदि के किसी भी प्रकार से संबंधित नहीं है, लेकिन क्योंकि अपवाद वर्ग __getitem __() को लागू करता है, और आर्ग टपल (ex.args) में मूल्यों वापस जाने के लिए इसे इस्तेमाल करता है। आप इस तथ्य से यह देख सकते हैं कि यदि आप स्ट्रिंग पर फिर से चलते हैं तो चरित्र-दर-चरित्र परिणाम के बजाय आपको पूर्ण स्ट्रिंग को पुनरावृत्ति में पहली और एकमात्र वस्तु मिलती है।

यह मुझे भी हैरान करता है, लेकिन इसके बारे में सोच रहा है, मुझे लगता है कि यह पीछे की संगतता कारणों के लिए है। पाइथन (pre-1.5) में अपवादों के वर्तमान वर्ग पदानुक्रम की कमी थी। इसके बजाए, तारों को फेंक दिया गया था, आमतौर पर (आमतौर पर) हैंडलिंग ब्लॉक को पारित किए जाने वाले किसी भी विवरण के लिए एक ट्यूपल तर्क। अर्थात्:

try: 
    raise "something failed", (42, "some other details") 
except "something failed", args: 
    errCode, msg = args 
    print "something failed. error code %d: %s" % (errCode, msg) 

ऐसा लगता है कि इस व्यवहार में डाल दिया गया था पूर्व 1.5 कोड, तर्कों की किसी टपल की उम्मीद नहीं बल्कि एक गैर iterable अपवाद वस्तु से तोड़ने से बचने के लिए। उपर्युक्त link

स्ट्रिंग अपवादों को थोड़ी देर के लिए हटा दिया गया है, और पाइथन 3 में जा रहे हैं। मैंने अब जांच की है कि पाइथन 3 अपवाद को कैसे संभालता है IOError के उदाहरण हैं। वस्तुओं, और ऐसा लगता है कि वे अब iterable देखते हैं:

>>> list(Exception("test")) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'Exception' object is not iterable 

[संपादित करें] चेक किए गए python3 के व्यवहार

+0

ब्रिलेंट! स्पष्टीकरण के लिए Thx। मैं जवाब स्वीकार करना चाहता हूं लेकिन ऐसा लगता है कि मुझे अनुमति देने से पहले कुछ और वोट चाहिए। –

3

मान्य नहीं है। ब्रायन anwser की जांच करें।

ठीक है, मैं सिर्फ यह मिल गया:

for x in Exception("test") : 
    print x 
    ....:  
    ....:  
test 

;-)

परेशान न हों वैसे भी, यह पता करने के लिए अच्छा है।

संपादित करें: टिप्पणियों को देखते हुए, मुझे कुछ स्पष्टीकरण जोड़ने लगता है।

एक अपवाद संदेश आप इन्स्टेन्शियशन दौरान करने के लिए पारित कर दिया शामिल हैं:

print Exception("test") 
test 
:

raise Exception("test") 

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
Exception: test 

यह कहना() वापस करती है कि संदेश क्या अपवाद सबसे अच्छी तरह परिभाषित है, इसलिए str उचित है

अब, ऐसा होता है कि अपवाद संदर्भ में कुछ और में उपयोग किए जाने पर अपवादों को पूरी तरह से स्ट्रिंग में परिवर्तित कर दिया जाता है।

तो मैं जब कार्य करें:

for x in Exception("test") : 
    print x 

मैं स्ट्रिंग "परीक्षण" से अधिक पुनरावृत्ति कर रहा हूँ।

और जब मैं करता हूँ:

for x in Exception() : 
    print x 

मैं कोई रिक्त स्ट्रिंग से अधिक पुनरावृति है। मुश्किल। क्योंकि जब यह अपनी समस्या से आता है:

try : 
    thing.merge(ExceptionLikeObject) 
except TypeError : 
    ... 

के बाद से ExceptionLikeObject स्ट्रिंग के रूप में माना जाता है यह कुछ भी आगे नहीं बढ़ेगी।

ठीक है, हम जानते हैं कि कैसे, लेकिन मैं अभी भी क्यों नहीं हूं। हो सकता है कि बिल्ट-इन अपवाद अंतर्निहित स्ट्रिंग से प्राप्त हो? क्योंकि जहाँ तक मैं जानता हूँ कि:

  • str जोड़ने किसी भी वस्तु iterable नहीं है।
  • मैंने iter ओवरलोडिंग द्वारा समस्या को छोड़ दिया, जिससे इसे टाइपररर बढ़ाया गया!

अब कोई समस्या नहीं है, लेकिन फिर भी एक रहस्य है।

+0

वास्तव में यह एक स्ट्रिंग के रूप में यह इलाज नहीं है, यह तर्क टपल रूप में यह इलाज है। यानी सूची (अपवाद ("परीक्षण")) == ["परीक्षण"], नहीं ["टी", "ई", "एस", "टी"]। इसी प्रकार सूची (अपवाद (1,2)) == [1, 2]। कुछ अटकलों के लिए नीचे मेरा उत्तर देखें कि यह क्यों हो सकता है। – Brian

2

असल में, मुझे अभी भी काफी कुछ नहीं मिला है।मैं देख सकता हूं कि एक अपवाद को फिर से अपवाद के लिए मूल तर्क देता है, मुझे यकीन नहीं है कि कोई भी ऐसा क्यों चाहेगा। प्रभावशाली पुनरावृत्ति मुझे लगता है कि पाइथन में कुछ गॉथस में से एक है जो अभी भी मुझे यात्रा करता है।

+0

यह अंतर्निहित पुनरावृत्ति नहीं है जो इसका कारण बनता है, यह अंतर्निहित कास्टिंग है। अपवाद स्वचालित रूप से एक स्ट्रिंग पर डाला जाता है, जो कि इष्टतम है। –

+0

वोट दिया गया कारण मुझे लगता है कि मतदान करना अनुचित है क्योंकि आप कुछ समझ में नहीं आते हैं। मैं अपने जवाब में और अधिक व्याख्या जोड़ूंगा। –

+0

@ जेसन: नहीं - अपवाद वास्तव में पैरामीटर की सूची के रूप में कार्य कर रहा है (यह __getitem__ लागू करता है)। यानी सूची (पूर्व) सूची के बराबर है (ex.args) मुझे यह भी अजीब लगता है - मुझे संदेह है कि यह पुराने स्ट्रिंग + टुपल शैली अपवादों के साथ पिछड़े संगतता कारणों के लिए इस तरह अभिनय कर रहा है। – Brian

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