Python Language
पायथन एंटी-पैटर्न
खोज…
क्लॉज को छोड़कर अति उत्साही
अपवाद शक्तिशाली होते हैं, लेकिन खंड को छोड़कर एक भी अति उत्साही इसे एक ही पंक्ति में दूर ले जा सकता है।
try: res = get_result() res = res[0] log('got result: %r' % res) except: if not res: res = '' print('got exception')
यह उदाहरण एंटीपैटर के 3 लक्षणों को प्रदर्शित करता है:
-
except
किसी अपवाद प्रकार (लाइन 5) को छोड़कर भी स्वस्थ अपवादों को पकड़ा जाएगा, जिसमेंKeyboardInterrupt
भी शामिल है। यह कार्यक्रम को कुछ मामलों में बाहर निकलने से रोकेगा। - अपवाद ब्लॉक त्रुटि को उत्पन्न नहीं करता है, जिसका अर्थ है कि हम यह नहीं बता पाएंगे कि अपवाद
get_result
भीतर से आया था या क्योंकिres
एक खाली सूची थी। - सबसे खराब, अगर हम परिणाम के बारे में चिंतित थे तो खाली होने के कारण, हमने कुछ बहुत बुरा किया है। यदि
get_result
विफल रहता है,res
पूरी तरह से सेट नहीं रहेगा, और तब के संदर्भres
ब्लॉक को छोड़कर में, बढ़ा देंगेNameError
, पूरी तरह से मूल त्रुटि मास्किंग।
हमेशा अपवाद के प्रकार के बारे में सोचें जिसे आप संभालने की कोशिश कर रहे हैं। अपवाद पृष्ठ को पढ़ें और यह महसूस करें कि क्या मूल अपवाद मौजूद हैं।
यहाँ ऊपर दिए गए उदाहरण का एक निश्चित संस्करण है:
import traceback try: res = get_result() except Exception: log_exception(traceback.format_exc()) raise try: res = res[0] except IndexError: res = '' log('got result: %r' % res)
हम अधिक विशिष्ट अपवादों को पकड़ते हैं, जहां आवश्यक हो, फिर से संगठित करना। कुछ और लाइनें, लेकिन असीम रूप से अधिक सही।
इससे पहले कि आप प्रोसेसर-गहन समारोह के साथ छलांग लगाएं
एक प्रोग्राम एक प्रोसेसर-गहन फ़ंक्शन को कई बार कॉल करके आसानी से समय बर्बाद कर सकता है।
उदाहरण के लिए, एक फ़ंक्शन लें जो इस तरह दिखता है: यह एक पूर्णांक देता है यदि इनपुट value
एक का उत्पादन कर सकता है, और None
:
def intensive_f(value): # int -> Optional[int]
# complex, and time-consuming code
if process_has_failed:
return None
return integer_output
और इसका उपयोग निम्नलिखित तरीके से किया जा सकता है:
x = 5
if intensive_f(x) is not None:
print(intensive_f(x) / 2)
else:
print(x, "could not be processed")
print(x)
जब भी यह काम करेगा, इसमें intensive_f
को कॉल करने की समस्या है, जो कोड को चलाने के लिए समय की लंबाई को दोगुना कर देता है। एक बेहतर समाधान यह होगा कि आप फंक्शन का रिटर्न वैल्यू पहले ही प्राप्त कर लें।
x = 5
result = intensive_f(x)
if result is not None:
print(result / 2)
else:
print(x, "could not be processed")
हालांकि, एक स्पष्ट और संभवतः अधिक पायथोनिक तरीका अपवादों का उपयोग करना है, उदाहरण के लिए:
x = 5
try:
print(intensive_f(x) / 2)
except TypeError: # The exception raised if None + 1 is attempted
print(x, "could not be processed")
यहां किसी अस्थायी चर की जरूरत नहीं है। अक्सर एक assert
कथन का उपयोग करना बेहतर हो सकता है, और इसके बजाय AssertionError
को पकड़ने के लिए।
शब्दकोश कुंजी
एक सामान्य उदाहरण जहां यह पाया जा सकता है, शब्दकोश कुंजी तक पहुंच रहा है। उदाहरण के लिए तुलना करें:
bird_speeds = get_very_long_dictionary()
if "european swallow" in bird_speeds:
speed = bird_speeds["european swallow"]
else:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
साथ में:
bird_speeds = get_very_long_dictionary()
try:
speed = bird_speeds["european swallow"]
except KeyError:
speed = input("What is the air-speed velocity of an unladen swallow?")
print(speed)
पहले उदाहरण के लिए दो बार शब्दकोश देखना पड़ता है, और जैसा कि यह एक लंबा शब्दकोश है, इसमें हर बार ऐसा करने में लंबा समय लग सकता है। दूसरे को केवल शब्दकोश के माध्यम से एक खोज की आवश्यकता होती है, और इस प्रकार बहुत सारे प्रोसेसर समय की बचत होती है।
इसका एक विकल्प यह है कि dict.get(key, default)
का उपयोग करें dict.get(key, default)
, हालांकि कई परिस्थितियों में इस बात के लिए अधिक जटिल संचालन की आवश्यकता हो सकती है कि कुंजी मौजूद नहीं है