क्‍लॉथ को छोड़कर सिवाय cause या Why का उपयोग किए सिंटैक्सएर्रर क्यों नहीं होता? क्या इसके लिए कोई वैध उपयोग है?


11

काम पर, मैं exceptएक orऑपरेटर के साथ एक खंड पर ठोकर खाई :

try:
    # Do something.
except IndexError or KeyError:
    # ErrorHandling

मुझे पता है कि अपवाद कक्षाओं को एक टपल के रूप में पारित किया जाना चाहिए, लेकिन इसने मुझे कहा कि यह भी कारण नहीं होगा SyntaxError

इसलिए पहले मैं जांच करना चाहता था कि क्या यह वास्तव में काम करता है। और यह नहीं है।

>>> def with_or_raise(exc):
...     try:
...         raise exc()
...     except IndexError or KeyError:
...         print('Got ya!')
...

>>> with_or_raise(IndexError)
Got ya!

>>> with_or_raise(KeyError)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in with_or_raise
KeyError

इसलिए यह दूसरा अपवाद नहीं पकड़ पाया, और बाइटकोड को देखते हुए, यह स्पष्ट हो गया कि क्यों:

>>> import dis
>>> dis.dis(with_or_raise)
  2           0 SETUP_EXCEPT            10 (to 12)

  3           2 LOAD_FAST                0 (exc)
              4 CALL_FUNCTION            0
              6 RAISE_VARARGS            1
              8 POP_BLOCK
             10 JUMP_FORWARD            32 (to 44)

  4     >>   12 DUP_TOP
             14 LOAD_GLOBAL              0 (IndexError)
             16 JUMP_IF_TRUE_OR_POP     20
             18 LOAD_GLOBAL              1 (KeyError)
        >>   20 COMPARE_OP              10 (exception match)
             22 POP_JUMP_IF_FALSE       42
             24 POP_TOP
             26 POP_TOP
             28 POP_TOP

  5          30 LOAD_GLOBAL              2 (print)
             32 LOAD_CONST               1 ('Got ya!')
             34 CALL_FUNCTION            1
             36 POP_TOP
             38 POP_EXCEPT
             40 JUMP_FORWARD             2 (to 44)
        >>   42 END_FINALLY
        >>   44 LOAD_CONST               0 (None)
             46 RETURN_VALUE

तो हम देख सकते हैं, निर्देश 14 पहले IndexErrorस्टैक पर कक्षा को लोड करता है । फिर यह जाँचता है कि क्या वह मूल्य है True, जो कि पायथन सत्यता के कारण है और अंत में सीधे निर्देश के लिए कूदता है 20 जहां exception matchयह किया जाता है। चूंकि निर्देश 18 को छोड़ दिया गया था, KeyErrorउसे स्टैक पर कभी भी लोड नहीं किया गया था और इसलिए यह मेल नहीं खाता।

मैंने पायथन 2.7 और 3.6 के साथ कोशिश की, एक ही परिणाम।

लेकिन फिर, यह मान्य सिंटैक्स क्यों है? मुझे लगता है कि यह निम्नलिखित में से एक है:

  1. यह पायथन के एक बहुत पुराने संस्करण से एक कलाकृति है।
  2. orएक exceptखंड के भीतर उपयोग करने के लिए वास्तव में एक वैध उपयोग मामला है ।
  3. यह केवल पायथन पार्सर की एक सीमा है जिसे exceptकीवर्ड के बाद किसी भी अभिव्यक्ति को स्वीकार करना पड़ सकता है ।

मेरा वोट 3 पर है (मैंने पायथन के लिए एक नए पार्सर के बारे में कुछ चर्चा देखी) लेकिन मुझे उम्मीद है कि कोई उस परिकल्पना की पुष्टि कर सकता है। क्योंकि अगर यह उदाहरण के लिए 2 था, तो मैं जानना चाहता हूं कि केस का उपयोग करें!

इसके अलावा, मैं उस खोज को कैसे जारी रखूंगा, इस बारे में थोड़ा स्पष्टता हूं। मुझे लगता है कि मुझे CPython parser के सोर्स कोड में खुदाई करनी होगी, लेकिन idk जहां इसे ढूंढना है और शायद वहाँ एक आसान तरीका है?

जवाबों:


7

में except e, eकोई भी मान्य पायथन अभिव्यक्ति हो सकती है:

try1_stmt ::=  "try" ":" suite
               ("except" [expression ["as" identifier]] ":" suite)+
               ...

[..] exceptएक अभिव्यक्ति के साथ एक खंड के लिए , उस अभिव्यक्ति का मूल्यांकन किया जाता है, और खंड अपवाद से मेल खाता है यदि परिणामी वस्तु अपवाद के साथ "संगत" है। ऑब्जेक्ट अपवाद के साथ संगत है यदि यह अपवाद ऑब्जेक्ट का वर्ग या आधार वर्ग है या अपवाद के साथ संगत आइटम युक्त टुपल है।

https://docs.python.org/3/reference/compound_stmts.html#the-try-statement

अभिव्यक्ति IndexError or KeyErrorमूल्य देता है IndexError। तो यह इसके बराबर है:

except IndexError:
   ...

उस तेज़ प्रकाश उत्तर के लिए धन्यवाद! क्या हम इसे पार्सर की सीमा (यानी केवल किसी भी अभिव्यक्ति को स्वीकार करने में सक्षम होने के बजाय अधिक विशिष्ट एक) या जानबूझकर पसंद करते हैं ताकि चीजों को बहुत अधिक प्रतिबंधित न किया जा सके?
Lo

1
यह मुझे सरल होने के बुनियादी पायथन सिद्धांतों से बेहतर लगता है। नए नियमों का आविष्कार क्यों करें जो केवल सीमित हो सकते हैं, जब किसी भी अभिव्यक्ति को स्वीकार करने का मतलब नए विशेष मामलों के बिना पूर्ण स्वतंत्रता है?
deceze

यह एक जानबूझकर पसंद है, एक को गतिशील रूप से पकड़ने और एक exceptबयान में इस तरह के मूल्य का उपयोग करके अपवादों का एक समूह इकट्ठा करने की अनुमति देता है ।
user4815162342

मुझे लगता है कि संभावनाओं को सीमित करने का कारण डेवलपर्स को कोड लिखने से रोकना होगा जो वह नहीं करता है जो वे करना चाहते थे। आखिरकार, लिखना लिखने के except IndexError or KeyErrorलिए एक सभ्य चीज की तरह दिखता है। हालाँकि मैं आपसे सहमत हूँ कि यह कुछ अन्य मूल्यों के खिलाफ होगा जो पायथन सम्मान करने की कोशिश करता है।
Loïc Teixeira

ध्यान दें कि अजगर भी अनुमति देता है var == 1 or 2, जो अप्रशिक्षित आंख को भी "लिखने के लिए एक सभ्य चीज की तरह दिखता है"।
एरिक

-2

आपको तार्किक अभिव्यक्ति के बजाय एक प्रकार के n-tuple का उपयोग करना चाहिए (जो सिर्फ पहला गैर-गलत तत्व लौटाता है):

def with_or_raise(exc):
  try:
    raise exc()
  except (IndexError,KeyError):
    print('Got ya!')

जैसा कि सवाल में कहा गया है, मुझे पता है कि अपवाद कक्षाओं को एक टपल के रूप में पारित किया जाना चाहिए लेकिन मैं सोच रहा था कि क्यों का उपयोग करना orअभी भी वैध पायथन था।
12:00 पर Loïc Teixeira
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.