कोशिश को छोड़कर ब्लॉक के साथ "बयान" के साथ अजगर का उपयोग करना


96

क्या एक कोशिश को छोड़कर ब्लॉक के साथ संयोजन में "बयान" के साथ अजगर का उपयोग करने का यह सही तरीका है ?:

try:
    with open("file", "r") as f:
        line = f.readline()
except IOError:
    <whatever>

यदि ऐसा है, तो चीजों को करने के पुराने तरीके पर विचार करना:

try:
    f = open("file", "r")
    line = f.readline()
except IOError:
    <whatever>
finally:
    f.close()

क्या यहाँ "के साथ" कथन का प्राथमिक लाभ यह है कि हम कोड की तीन पंक्तियों से छुटकारा पा सकते हैं? ऐसा नहीं लगता है कि मुझे इस उपयोग के मामले के लिए मजबूर किया गया है (हालांकि मैं समझता हूं कि "के साथ" बयान के अन्य उपयोग हैं)।

EDIT: क्या कोड के उपरोक्त दो ब्लॉकों की कार्यक्षमता समान है?

EDIT2: पहले कुछ उत्तर आमतौर पर "के साथ" का उपयोग करने के लाभों के बारे में बात करते हैं, लेकिन यहां सीमांत लाभ के बारे में लगता है। हम सभी वर्षों से स्पष्ट रूप से f.close () बुला रहे हैं (या होना चाहिए)। मुझे लगता है कि एक फायदा यह है कि मैला कोडर "के साथ" का उपयोग करने से लाभ होगा।



मेरे लिए, अंत में बयान में चीजों को बंद () करने के लिए याद नहीं रखना 'के साथ' का उपयोग करने का एक अच्छा पर्याप्त कारण है। मैंने अपने संसाधनों को बंद करने में बहुत सारे कोड फेल होते देखे हैं। और 'के साथ' में कमियां नहीं हैं जहां तक ​​मैं देख सकता हूं।
राउल सालिनास-मोंटेगूडो

जवाबों:


139
  1. आपके द्वारा दिए गए दो कोड ब्लॉक समकक्ष नहीं हैं
  2. आपके द्वारा चीजों को करने के पुराने तरीके के रूप में वर्णित कोड में एक गंभीर बग है: फ़ाइल खोलने में विफल होने पर आपको finallyक्लॉज़ में दूसरा अपवाद मिलेगा क्योंकि fबाध्य नहीं है।

समतुल्य पुरानी शैली कोड होगा:

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>

जैसा कि आप देख सकते हैं, withबयान चीजों को कम त्रुटि वाला बना सकता है। पायथन (2.7, 3.1) के नए संस्करणों में, आप एक withबयान में कई अभिव्यक्तियों को भी जोड़ सकते हैं । उदाहरण के लिए:

with open("input", "r") as inp, open("output", "w") as out:
    out.write(inp.read())

इसके अलावा, मैं व्यक्तिगत रूप से इसे जितनी जल्दी हो सके किसी भी अपवाद को पकड़ने के लिए बुरी आदत के रूप में मानता हूं। यह अपवादों का उद्देश्य नहीं है। यदि IO फ़ंक्शन जो विफल हो सकता है वह अधिक जटिल ऑपरेशन का हिस्सा है, ज्यादातर मामलों में IOError को पूरे ऑपरेशन को निरस्त करना चाहिए और इसलिए बाहरी स्तर पर नियंत्रित किया जाना चाहिए। withबयानों का उपयोग करके , आप try...finallyआंतरिक स्तरों पर इन सभी कथनों से छुटकारा पा सकते हैं ।


7

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

और हाँ, जिस तरह से आपने संयुक्त किया है withऔर try-exceptयह करने का एकमात्र तरीका है, क्योंकि असाधारण त्रुटियों के कारण openबयान को withब्लॉक के भीतर ही पकड़ा नहीं जा सकता है ।


1

मुझे लगता है कि आपको "कथन" के बारे में यह गलत लगा कि यह केवल लाइनें कम करता है। यह वास्तव में आरंभीकरण करता है और अशांति को संभालता है।

आपके मामले में "के साथ" करता है

  • एक फ़ाइल खोलो,
  • इसकी सामग्री को संसाधित करें, और
  • इसे बंद करना सुनिश्चित करें।

यहाँ "समझ के साथ" बयान के लिए लिंक है: http://effbot.org/zone/python-with-statement.htm

संपादित करें: हाँ "के साथ" का आपका उपयोग सही है और कोड के दोनों ब्लॉकों की कार्यक्षमता समान है। "क्यों" का उपयोग करने के बारे में प्रश्न? यह इसलिए है क्योंकि इससे आपको लाभ मिलता है। जैसे आपने गलती से लापता f.close () के बारे में उल्लेख किया है।


-4

निम्नलिखित कोड के लिए अधिक पायथोनिक तरीका है:

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>

try:
    f = open("file", "r")
except IOError:
    <whatever>
else:
    f.close()

1
मैंने आपके लिए कोड स्वरूपण जोड़ा है; यह पढ़ने में आसान बनाता है। लेकिन आप यह सुनिश्चित करने के लिए दोबारा जांच कर सकते हैं कि मैंने इंडेंटिंग नहीं तोड़ी है।
एंड्री

2
नहीं, आपका संस्करण मूल कोड के समान कार्य नहीं करता है। यदि आप अनुपलब्ध readline()कॉल जोड़ते हैं , तो readline()परिणाम में यदि आपका संस्करण फ़ाइल बंद नहीं करता है IOError
अलेक्सी तोरमो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.