दिलचस्प पोस्ट
स्थिर तरीके मजाक पता लगाएँ कि किस शाखा को एक स्थानीय शाखा ट्रैकिंग कर रही है DataContractJsonSerializer बनाने के लिए कोई भी तरीका ठीक से शब्दकोशों को सीरियल कर सकता है? स्ट्रिंग से अंतिम वर्ण निकालें एक JTable में समस्या स्वरूपण फ़ील्ड – पूर्णांक और डबल के बीच अंतर WPF और इकाई फ़्रेमवर्क के साथ डेटाएनेटेशन का उपयोग कर डेटा सत्यापित करें? सेलेरी में कार्य स्थिति की जांच कैसे करें? Node.js के साथ सिंक्रोनस डेटाबेस क्वेरीज़ अंतिम पत्र रंग बदलें पायथन दशमलव प्रारूप एक .NET डेटटाइम के मिलिसेकंड को कैसे छोटा करना jQuery और टिंइएमईईई: टेडेरेआ वैल्यू प्रस्तुत नहीं होता है एक संकेतक को एक शाब्दिक (या निरंतर) वर्ण सरणी (स्ट्रिंग) में लौट रहा है? मैटलब में लम्बाई एन्कोडिंग चलाएं JSON और असमर्थित क्षेत्रों से निपटने

"क्षमा की अनुमति नहीं पूछो" – समझाएं

मैं इस दर्शन के बारे में व्यक्तिगत "धार्मिक" विचारों के लिए नहीं कह रहा हूं, बल्कि कुछ और तकनीकी

मैं समझता हूं कि यह वाक्यांश कई लिटमस परीक्षणों में से एक है, यह देखने के लिए कि आपका कोड "पायथनिक" है। लेकिन मेरे लिए, अजगर का मतलब साफ, सरल और सहज है, खराब कोडिंग के लिए अपवाद संचालकों के साथ लोड नहीं किया गया है।

तो, व्यावहारिक उदाहरण। मैं एक वर्ग को परिभाषित करता हूं:

class foo(object): bar = None def __init__(self): # a million lines of code self.bar = "Spike is my favorite vampire." # a million more lines of code 

अब, एक प्रक्रियात्मक पृष्ठभूमि से आ रहा है, दूसरे फ़ंक्शन में मैं यह करना चाहता हूं:

 if foo.bar: # do stuff 

यदि मैं अधीर था और प्रारंभिक फू = कोई नहीं किया तो मुझे एक विशेषता अपवाद मिलेगा तो, "क्षमा की अनुमति नहीं पूछो" से सुझाव मिलता है कि मुझे इसके बजाय क्या करना चाहिए?

 try: if foo.bar: # do stuff except: # this runs because my other code was sloppy? 

मुझे एक कोशिश ब्लॉक में अतिरिक्त तर्क जोड़ने के लिए क्यों बेहतर होगा, इसलिए मैं अपनी कक्षा की परिभाषा को और अधिक अस्पष्ट छोड़ सकता / सकती हूं? क्यों नहीं शुरू में सब कुछ परिभाषित, स्पष्ट अनुमति दे दी है ?

(कोशिश करो / ब्लॉकों को छोड़कर मुझे का उपयोग करने के बारे में मुझे मत मारो … मैं उन्हें हर जगह का उपयोग करता हूं। मुझे नहीं लगता कि ये मेरी सही त्रुटियों को पकड़ने के लिए इस्तेमाल करना सही है क्योंकि मैं पूरी तरह से प्रोग्रामर नहीं था।

या … क्या मैं पूरी तरह से "माफी से पूछो" मंत्र को गलत समझूं?

वेब के समाधान से एकत्रित समाधान ""क्षमा की अनुमति नहीं पूछो" – समझाएं"

शास्त्रीय "माफी की अनुमति नहीं मांगते" उदाहरण एक ऐसे शब्द से मूल्य तक पहुंच रहा है जो अस्तित्व में नहीं है। उदाहरण के लिए:

 names = { 'joe': 'Joe Nathan', 'jo': 'Jo Mama', 'joy': 'Joy Full' } name = 'hikaru' try: print names[name] except KeyError: print "Sorry, don't know this '{}' person".format(name) 

यहां हो सकता है कि अपवाद ( KeyError ) कहा गया है, ताकि आप हर त्रुटि के लिए माफी नहीं मांग रहे हों, लेकिन केवल एक ही स्वाभाविक रूप से हो सकता है। तुलना के लिए, "पहले अनुमति पूछें" दृष्टिकोण ऐसा दिखे:

 if name in names: print names[name] else: print "Sorry, don't know this '{}' person".format(name) 

या

 real_name = names.get(name, None) if real_name: print real_name else: print "Sorry, don't know this '{}' person".format(name) 

"क्षमा मांगना" के ऐसे उदाहरण अक्सर बहुत सरल होते हैं। आईएमओ यह स्पष्ट नहीं है कि ब्लॉकों को except / else तुलना में स्वाभाविक रूप से बेहतर / if वास्तविक मूल्य बहुत स्पष्ट है जब आप विभिन्न तरीकों से असफल हो सकते हैं – जैसे पार्सिंग; eval() का उपयोग करना; ऑपरेटिंग सिस्टम, मिडलवेयर, डेटाबेस, या नेटवर्क संसाधनों तक पहुंच; या जटिल गणित का प्रदर्शन जब कई संभावित विफलता मोड होते हैं, तो माफी पाने के लिए तैयार रहना बेहद मूल्यवान है।

आपके कोड उदाहरणों के बारे में अन्य नोट:

आपको हर चर के उपयोग के पीछे के ब्लॉक except / try करने की आवश्यकता नहीं है। यह भयानक होगा। और आपको अपने __init__() में self.bar को सेट करने की ज़रूरत नहीं है, क्योंकि यह आपकी class परिभाषा में निर्धारित है। यह कक्षा में या तो परिभाषित करने के लिए सामान्य है (यदि यह डेटा कक्षा के सभी उदाहरणों में साझा किया जा सकता है) या __init__() (यदि यह उदाहरण है, प्रत्येक उदाहरण के लिए विशिष्ट) में है।

किसी के मूल्य को अनिर्धारित None है, या एक त्रुटि, जिस तरह से। यह एक विशिष्ट और वैध मान है, जिसका अर्थ है कोई नहीं, शून्य, शून्य या कुछ भी नहीं। कई भाषाओं में ऐसे मूल्य हैं, ताकि प्रोग्रामर 0 , -1 , '' (खाली स्ट्रिंग) या समान उपयोगी मूल्यों को "ओवरलोड" न करें।

"क्षमा पूछो, अनुमति नहीं" दो प्रोग्रामिंग शैलियों का विरोध करते हैं "अनुमति के लिए पूछें" इस तरह से चला जाता है:

 if can_do_operation(): perform_operation() else: handle_error_case() 

"क्षमा पूछो" इस तरह से चला जाता है:

 try: perform_operation() except Unable_to_perform: handle_error_case() 

यह एक ऐसी स्थिति है जहां यह उम्मीद की जाती है कि आपरेशन करने का प्रयास विफल हो सकता है, और आपको ऐसी परिस्थिति को संभालना होगा जहां ऑपरेशन असंभव है, एक ही रास्ता या कोई अन्य। उदाहरण के लिए, यदि ऑपरेशन एक फ़ाइल तक पहुंच रहा है, तो फ़ाइल मौजूद नहीं हो सकती है।

माफी के लिए पूछना बेहतर क्यों दो मुख्य कारण हैं:

  • एक समवर्ती दुनिया में (एक multithreaded कार्यक्रम में, या यदि ऑपरेशन में ऐसे प्रोग्राम शामिल हैं, जैसे कि फाइल, अन्य प्रक्रियाओं, नेटवर्क संसाधनों आदि), तो स्थिति उस समय के बीच बदल सकती है जब आप can_do_operation() चलाते हैं और जब आप perform_operation() चलाते हैं तो आपको वैसे भी त्रुटि को संभालना होगा।
  • अनुमति के लिए आपको सही मानदंड का उपयोग करने की आवश्यकता है यदि आप इसे गलत प्राप्त करते हैं, तो आप या तो कोई कार्य निष्पादित करने में असमर्थ होंगे जो आप कर सकते थे, या कोई त्रुटि हुई क्योंकि आप सभी के बाद ऑपरेशन नहीं कर सकते। उदाहरण के लिए, यदि आप जांचते हैं कि कोई फ़ाइल खोलने से पहले मौजूद है, तो यह संभव है कि फ़ाइल मौजूद है, लेकिन आप इसे नहीं खोल सकते क्योंकि आपके पास अनुमति नहीं है इसके विपरीत, हो सकता है कि फाइल को तब खोल दिया जाए जब आप उसे खोलते हैं (उदाहरण के लिए क्योंकि यह एक नेटवर्क कनेक्शन पर आता है, जो कि वास्तव में फ़ाइल खोलते समय लाया जाता है, न कि जब आप केवल यह देखने के लिए कि क्या यह वहां है)।

पूछने-माफी की स्थिति में क्या समान है, यह है कि आप एक ऑपरेशन करने का प्रयास कर रहे हैं, और आप जानते हैं कि ऑपरेशन विफल हो सकता है।

जब आप foo.bar , तो bar के गैर-अस्तित्व को सामान्यतः ऑब्जेक्ट foo की विफलता नहीं माना जाता है। यह आम तौर पर एक प्रोग्रामर त्रुटि है: किसी ऑब्जेक्ट को ऐसे तरीके से उपयोग करने का प्रयास करना जिस तरह से इसे डिज़ाइन नहीं किया गया था। पायथन में एक प्रोग्रामर त्रुटि का नतीजा एक अप्रबंधित अपवाद है (यदि आप भाग्यशाली हैं: निश्चित तौर पर, कुछ प्रोग्रामर त्रुटियों को स्वचालित रूप से नहीं पहचाना जा सकता है)। इसलिए यदि bar ऑब्जेक्ट का एक वैकल्पिक हिस्सा है, तो इसका सामना करने के लिए सामान्य तरीके से एक bar फ़ील्ड है जिसे किसी के लिए आरम्भ किया गया है, और वैकल्पिक भाग मौजूद होने पर कुछ अन्य मूल्य पर सेट किया गया है। यह जांचने के लिए कि bar मौजूद है, लिखिए

 if foo.bar != None: handle_optional_part(foo.bar) else: default_handling() 

आप संक्षिप्त if foo.bar != None: to if foo.bar: केवल अगर bar हमेशा सही होगा जब बुलियन के रूप में व्याख्या की जाएगी – यदि bar 0, [] , {} या किसी अन्य वस्तु को गलत सच्चाई हो सकती है मूल्य, आपको की आवश्यकता है != None यह भी स्पष्ट है, यदि आप एक वैकल्पिक भाग के लिए परीक्षण कर रहे हैं (जैसा कि True और False बीच परीक्षण के विपरीत)।

इस बिंदु पर आप पूछ सकते हैं: क्यों नहीं bar के प्रारंभिकरण को छोड़ दें, जब वह वहां नहीं है, और hasattr साथ अपनी उपस्थिति का परीक्षण करें या उसे AttributeError hasattr हैंडलर के साथ पकड़ लें? क्योंकि आपका कोड केवल दो मामलों में समझ में आता है:

  • ऑब्जेक्ट में कोई bar फ़ील्ड नहीं है;
  • ऑब्जेक्ट में एक bar फ़ील्ड है जिसका अर्थ है कि आप क्या सोचते हैं इसका मतलब है।

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

आप सही हैं – try और except का उद्देश्य आपके ढीला कोडिंग को कवर नहीं करना है। यह सिर्फ अधिक ढीली कोडिंग की ओर जाता है

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

मेरा व्यक्तिगत गैर-धार्मिक राय यह है कि यह कहा गया है कि मंत्र मुख्य रूप से प्रलेखित और अच्छी तरह से समझने वाली निकास स्थितियों और बढ़त वाले मामलों (जैसे आई / ओ त्रुटियों) पर लागू होता है, और स्लॉपी प्रोग्रामिंग के लिए आउट-ऑफ-जेल कार्ड के रूप में कभी भी उपयोग नहीं किया जाना चाहिए।

उस ने कहा, try/except अक्सर इसका इस्तेमाल किया जाता है जब "बेहतर" विकल्प मौजूद होते हैं। उदाहरण के लिए:

 # Do this value = my_dict.get("key", None) # instead of this try: value = my_dict["key"] except KeyError: value = None 

आपके उदाहरण के लिए, if hasattr(foo, "bar") उपयोग करें if hasattr(foo, "bar") यदि आपके पास foo पर कोई नियंत्रण नहीं है और अपनी अपेक्षाओं के अनुरूप होने की जांच करने की आवश्यकता है, अन्यथा बस foo.bar उपयोग foo.bar और परिणामी त्रुटि को पहचानने और फिक्स करने के लिए आपका मार्गदर्शन करें मैला कोड

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

 d = {} k = "k" if k in d.keys(): print d[k] else: print "key \"" + k + "\" missing" 

लेकिन परिणामस्वरूप त्रुटि को संभालने के लिए यदि कुंजी अनुपलब्ध है:

 d = {} k = "k" try: print d[k] except KeyError: print "key \"" + k + "\" missing" 

हालांकि, बिंदु को प्रत्येक को बदलने की ज़रूरत नहीं है if आपके कोड में एक try / except ; जो आपके कोड को निश्चित रूप से मैसियर बना देगा। इसके बजाय आपको केवल त्रुटियों को पकड़ना चाहिए जहां आप उनके बारे में कुछ कर सकते हैं। आदर्श रूप से यह आपके कोड में समग्र त्रुटि प्रबंधन की मात्रा को कम कर देगा, इसके वास्तविक उद्देश्य को और अधिक स्पष्ट बना देगा।

क्षमा करें अनुमति की अनुमति कोड को आसान बनाने के लिए नहीं है। इसका अर्थ कोड को इस तरह लिखा जाना है जब कोई उचित उम्मीद है। बार एक एट्रिब्यूट .bar को ट्रिगर कर सकता है।

  try: print foo.bar except AttributeError as e print "No Foo!" 

आपका कोड दोनों अनुमति और माफी पूछने लगता है 🙂

बात यह है, यदि आप कुछ असफल होने की उम्मीद करते हैं, तो एक कोशिश / पकड़ का उपयोग करें यदि आप कुछ विफल होने की उम्मीद नहीं करते हैं, और यह वैसे भी विफल हो जाता है, तो अच्छी तरह से अपवाद जो फेंका जाता है, वह अन्य भाषाओं में असफल दावा के बराबर हो जाता है। आप देखेंगे कि अप्रत्याशित अपवाद कहाँ हो रहा है और तदनुसार आपके कोड / मान्यताओं को समायोजित कर सकता है।

यहां बहुत सारे अच्छे उत्तर दिए गए हैं, मैंने सोचा कि मैं एक बिंदु जोड़ूंगा जो मैंने अभी तक उल्लेख नहीं किया है।

अनुमति के बजाय अक्सर माफी मांगने के लिए प्रदर्शन में सुधार होता है।

  • जब आप अनुमति के लिए पूछते हैं, तो आपको हर बार अनुमति के लिए पूछने के लिए एक अतिरिक्त ऑपरेशन करना होगा।
  • माफी मांगते समय, आपको केवल एक अतिरिक्त कार्रवाई करना पड़ता है, यानी जब यह विफल हो जाता है।

आमतौर पर असफलता के मामले दुर्लभ होते हैं, जिसका अर्थ है कि यदि आप केवल अनुमति के लिए पूछ रहे हैं, तो आपको कभी भी कोई अतिरिक्त कार्य करना पड़ता है हां, जब यह असफल हो जाता है, यह एक अपवाद फेंकता है, साथ ही एक अतिरिक्त कार्य निष्पादित करता है, लेकिन अजगर में अपवाद बहुत तेज़ है आप यहां कुछ समय देख सकते हैं: https://jeffknupp.com/blog/2013/02/06/write-cleaner-python-use-exceptions/