पायथन में पुनरावृत्तियों एक अपवाद क्यों उठाते हैं?


48

यहाँ जावा में पुनरावृत्तियों के लिए वाक्यविन्यास है (C # में कुछ समान सिंटैक्स):

Iterator it = sequence.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

जो समझ में आता है। यहाँ पायथन में बराबर सिंटैक्स है:

it = iter(sequence)
while True:
    try:
        value = it.next() 
    except StopIteration:
        break
    print(value)

मैंने सोचा था कि अपवादों का उपयोग केवल अच्छी तरह से, असाधारण परिस्थितियों में किया जाना चाहिए था।

पायथन अपवादों को रोकने के लिए अपवादों का उपयोग क्यों करता है?


जवाबों:


50

स्पष्ट रूप से एक प्रयास को छोड़कर ब्लॉक के बिना उस अभिव्यक्ति को लिखने के लिए एक बहुत ही आकर्षक तरीका है StopIteration:

# some_iterable is some collection that can be iterated over
# e.g., a list, sequence, dict, set, itertools.combination(...)

for value in some_iterable:
    print(value)

आप संबंधित पीईपी 234 255 पर पढ़ सकते हैं यदि आप अधिक जानना चाहते हैं कि क्यों StopIterationपेश किया गया था और पुनरावृत्तियों के पीछे तर्क।

अजगर में एक सामान्य सिद्धांत कुछ करने (देखने import this) का एक तरीका है , और अधिमानतः इसका सुंदर, स्पष्ट, पठनीय और सरल है, जो कि पायथोनिक विधि को संतुष्ट करता है। आपका समतुल्य कोड केवल आवश्यक है क्योंकि अजगर पुनरावृत्तियों को hasNextसदस्य कार्य नहीं देता है ; लोगों को सीधे चलने वालों के माध्यम से सीधे लूप के लिए प्राथमिकता देना (और अगर आपको इसे पढ़ने की कोशिश करने और अपवाद को पकड़ने के लिए कुछ और करने की आवश्यकता है)।

StopIterationइट्रेटर के अंत में एक अपवाद को पकड़ने का यह स्वत: पकड़ समझ में आता है और EOFErrorयदि आप फ़ाइल के अंत में पढ़ते हैं तो यह उठाया का एक एनालॉग है ।


6
"पायथन" रास्ता निश्चित रूप से "अनुक्रम में मूल्य के लिए" की तरह बहुत अधिक लगता है: "इसके बजाय" मूल्य (क्रम) में मूल्य के लिए: ".. अपडेट पोस्ट?
यम मार्कोविच

15
@ यम: मैं सहमत हूँ। एक मौजूदा अनुक्रम लेने के लिए इसकी पाइथोनिक नहीं है और इसे एक लूप में बदलने के लिए इसे लूप के लिए लागू करने के लिए; अनुक्रम पहले से ही एक iterable है, तो एक के रूपांतरण listएक करने के लिए listiteratorव्यर्थ है। मैं केवल NullUserException के शुरुआती बिंदु का पालन करने, आप कैसे करना चाहिए पुनरावर्तक, जो एक ही तरीका है अधिक पाश आपको चाहिए किसी भी iterable से अधिक लूप (समझाने के लिए पहली पंक्ति रखा list, set, str, tuple, dict, file, generator, आदि)। मैं कुछ ऐसा कर सकता था जैसे it = itertools.combinations("ABCDE", 2)एक सार्थक पुनरावृत्त का बेहतर उदाहरण प्राप्त करने के लिए।
ड्रिंक जिंबोब

1
it = iter(sequence)आवश्यकता नहीं है।
कारिडोरक

2
@Caridorc - यदि आप टिप्पणियों को पढ़ते हैं, तो आप अपनी बात को संबोधित करेंगे। यह आवश्यक नहीं है और प्रश्न के शुरुआती बिंदु का पालन करने के लिए किया गया था (जहां वे स्पष्ट रूप से पूछ रहे थे iterators) और आपको iterस्पष्ट रूप से iterator(कोशिश type([])( list) बनाम type(iter([]))( listiterator)) उत्पन्न करने की आवश्यकता है ।
jimbob

//, @drjimbob, आप इस प्रश्न के लिए दूसरी टिप्पणी में एक उत्कृष्ट बिंदु उठाते हैं। मैं पुनरावृत्तियों की उन्नत सुविधाओं के लिए थोड़ा नया हूँ, और मुझे लगता है कि अगर मैं टिप्पणियों को नहीं पढ़ा होता, तो मैं इसे नहीं पकड़ता। मुझे लगता है कि यह हम में से कई गरीब आत्म-शिक्षित आत्माओं को लाभान्वित करेगा यदि हम उस बिंदु को देख सकते हैं कि इस प्रश्न को उत्तर के पहले, मुख्य भाग के रूप में "द पायथन वे" में कैसे बदला जा सकता है ।
नाथन बसानी

28

पायथन 234 में दस्तावेजीकरण को रोकने के लिए अजगर एक अपवाद का उपयोग क्यों करता है :

यह सवाल किया गया है कि क्या पुनरावृति के अंत को इंगित करने के लिए एक अपवाद बहुत महंगा नहीं है। StopIteration अपवाद के लिए कई विकल्प प्रस्तावित किए गए हैं: एक विशेष मान अंत को इंगित करने के लिए, एक फ़ंक्शन अंत () यह परीक्षण करने के लिए कि क्या इट्रेटर समाप्त हो गया है, यहां तक ​​कि IndexError अपवाद का पुन: उपयोग करना।

  • एक विशेष मूल्य में यह समस्या होती है कि यदि किसी अनुक्रम में कभी भी वह विशेष मूल्य होता है, तो उस अनुक्रम पर एक लूप बिना किसी चेतावनी के समय से पहले समाप्त हो जाएगा। यदि अशक्त-सी सी स्ट्रिंग के साथ अनुभव ने हमें उन समस्याओं को नहीं सिखाया है जो यह पैदा कर सकते हैं, तो मुसीबत की कल्पना करें कि पायथन आत्मनिरीक्षण उपकरण सभी अंतर्निहित नामों की सूची पर पुनरावृत्ति होगा, यह मानते हुए कि विशेष अंतिम मूल्य एक अंतर्निहित था नाम में!

  • अंत () फ़ंक्शन को कॉल करने के लिए प्रति पुनरावृत्ति दो कॉल की आवश्यकता होगी। एक कॉल के अलावा दो कॉल बहुत अधिक महंगी हैं और एक अपवाद के लिए एक परीक्षण है। विशेष रूप से लूप के लिए समय-महत्वपूर्ण एक अपवाद के लिए बहुत सस्ते में परीक्षण कर सकता है।

  • IndexError का पुन: उपयोग भ्रम पैदा कर सकता है क्योंकि यह एक वास्तविक त्रुटि हो सकती है, जिसे समय से पहले लूप को समाप्त करके मास्क किया जाएगा।

नोट: एक अनुक्रम पर लूप करने के लिए मुहावरेदार तरीका इस तरह है:

for value in sequence:
    print (value)

20

यह दर्शन में अंतर है। पायथोनिक डिजाइन दर्शन ईएएफपी है :

अनुमति की तुलना में क्षमा मांगना आसान है। यह सामान्य पायथन कोडिंग शैली वैध कुंजी या विशेषताओं के अस्तित्व को मानती है और यदि अपवाद गलत साबित होता है तो अपवादों को पकड़ता है। यह साफ और तेज शैली कई tryऔर exceptबयानों की उपस्थिति की विशेषता है । तकनीक LBYL शैली के साथ कई अन्य भाषाओं जैसे C के समान है ...


7

यह सिर्फ इतना है कि जावा कार्यान्वयन की एक hasNext()विधि है ताकि आप खाली प्रदर्शन करने से पहले एक खाली पुनरावृत्ति के लिए जांच कर सकें next()। जब आप next()जावा इट्रेटर पर कॉल करते हैं जिसमें कोई तत्व नहीं बचा है, NoSuchElementExceptionतो फेंक दिया जाता है

तो प्रभावी रूप से, आप एक कोशिश कर सकते हैं..जैसी जावा में कोशिश की तरह .. पायथन में। और हाँ, पिछले उत्तर के अनुसार, पाइथोनिक दुनिया में दर्शन बहुत महत्वपूर्ण है।

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