Python Language
अपवाद
खोज…
परिचय
निष्पादन के दौरान पाई गई त्रुटियों को अपवाद कहा जाता है और यह बिना शर्त घातक नहीं हैं। अधिकांश अपवाद कार्यक्रमों द्वारा नियंत्रित नहीं किए जाते हैं; उन प्रोग्रामों को लिखना संभव है जो चयनित अपवादों को संभालते हैं। अपवाद और अपवाद तर्क से निपटने के लिए पायथन में विशिष्ट विशेषताएं हैं। इसके अलावा, अपवादों में एक समृद्ध प्रकार की पदानुक्रम है, जो सभी BaseException
प्रकार से विरासत में मिली हैं।
वाक्य - विन्यास
- अपवाद उठाना
- पहले से उठाए गए एक अपवाद को फिर से बढ़ाएं
- सेट अपवाद कारण - कारण # अजगर 3 से उठाने के अपवाद
- # पायथन 3 से कोई भी अपवाद न उठाएं - सभी अपवाद संदर्भ को दबा दें
- प्रयत्न:
- [अपवाद टाइप] सिवाय [पहचानकर्ता के रूप में]:
- अन्य:
- आखिरकार:
अपवाद उठाना
यदि आपका कोड एक ऐसी स्थिति का सामना करता है जो यह नहीं जानता कि कैसे संभालना है, जैसे कि एक गलत पैरामीटर, तो इसे उचित अपवाद उठाना चाहिए।
def even_the_odds(odds):
if odds % 2 != 1:
raise ValueError("Did not get an odd number")
return odds + 1
अपवादों को पकड़ना
का प्रयोग try...except:
अपवादों को पकड़ने के लिए। आपको सटीक अपवाद के रूप में निर्दिष्ट करना चाहिए जितना आप कर सकते हैं:
try:
x = 5 / 0
except ZeroDivisionError as e:
# `e` is the exception object
print("Got a divide by zero! The exception was:", e)
# handle exceptional case
x = 0
finally:
print "The END"
# it runs no matter what execute.
अपवाद वर्ग जो निर्दिष्ट है - इस मामले में, ZeroDivisionError
- उस अपवाद को पकड़ता है जो उस वर्ग का है या उस अपवाद के किसी उपवर्ग का है।
उदाहरण के लिए, ZeroDivisionError
ArithmeticError
का एक उपवर्ग है:
>>> ZeroDivisionError.__bases__
(<class 'ArithmeticError'>,)
और इसलिए, निम्नलिखित अभी भी ZeroDivisionError
को ZeroDivisionError
:
try:
5 / 0
except ArithmeticError:
print("Got arithmetic error")
अंत में साथ सफाई कोड चल रहा है
कभी-कभी, आप कुछ भी घटित करना चाह सकते हैं, चाहे जो भी अपवाद हुआ हो, उदाहरण के लिए, यदि आपको कुछ संसाधनों को साफ करना है।
किसी भी अपवाद को उठाए जाने के बावजूद एक try
खंड का finally
ब्लॉक होगा।
resource = allocate_some_expensive_resource()
try:
do_stuff(resource)
except SomeException as e:
log_error(e)
raise # re-raise the error
finally:
free_expensive_resource(resource)
इस पैटर्न को अक्सर संदर्भ प्रबंधकों ( कथन के with
) का उपयोग करके बेहतर तरीके से नियंत्रित किया जाता है।
अपवादों को फिर से उठाना
कभी-कभी आप केवल अपवादों का निरीक्षण करने के लिए अपवाद को पकड़ना चाहते हैं, जैसे कि लॉगिंग उद्देश्यों के लिए। निरीक्षण के बाद, आप चाहते हैं कि अपवाद का प्रचार जारी रहे जैसा कि पहले हुआ था।
इस मामले में, बस बिना किसी पैरामीटर के साथ raise
कथन का उपयोग करें।
try:
5 / 0
except ZeroDivisionError:
print("Got an error")
raise
हालांकि, ध्यान रखें कि कॉलर स्टैक में आगे कोई व्यक्ति अभी भी अपवाद को पकड़ सकता है और इसे किसी तरह से संभाल सकता है। किया गया आउटपुट इस मामले में एक उपद्रव हो सकता है क्योंकि यह किसी भी मामले में होगा (पकड़ा गया या पकड़ा नहीं गया)। इसलिए एक अलग अपवाद को उठाना एक बेहतर विचार हो सकता है, जिसमें आपकी टिप्पणी के साथ-साथ मूल अपवाद के बारे में टिप्पणी भी शामिल है:
try:
5 / 0
except ZeroDivisionError as e:
raise ZeroDivisionError("Got an error", e)
लेकिन इसके अपवाद अपवाद को कम करने का दोष यह है कि इसे raise
जबकि तर्क के बिना raise
मूल अपवाद ट्रेस को बरकरार रखता है।
अजगर 3 में आप का उपयोग करके मूल ढेर रख सकते raise
- from
वाक्य रचना:
raise ZeroDivisionError("Got an error") from e
चेन अपवादों को बढ़ाने के साथ
एक अपवाद को संभालने की प्रक्रिया में, आप एक और अपवाद उठाना चाह सकते हैं। उदाहरण के लिए, यदि आपको किसी फ़ाइल से पढ़ते समय एक IOError
मिलती है, तो आप इसके बजाय अपने लाइब्रेरी के उपयोगकर्ताओं को प्रस्तुत करने के लिए एक एप्लिकेशन-विशिष्ट त्रुटि उठाना चाह सकते हैं।
आप अपवादों की श्रृंखला को दिखा सकते हैं कि अपवादों की हैंडलिंग कैसे आगे बढ़ी:
>>> try:
5 / 0
except ZeroDivisionError as e:
raise ValueError("Division failed") from e
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
ValueError: Division failed
अपवाद पदानुक्रम
अपवाद कक्षाओं की विरासत संरचना द्वारा निर्धारित अपवाद पदानुक्रम के आधार पर अपवाद हैंडलिंग होती है।
उदाहरण के लिए, IOError
और OSError
दोनों ही EnvironmentError
उपवर्ग हैं। कोड है कि एक कैच IOError
एक पकड़ नहीं होगा OSError
। हालाँकि, जो कोड एक EnvironmentError
को पकड़ता है, वह IOError
और OSError
दोनों को पकड़ OSError
।
अंतर्निहित अपवादों का पदानुक्रम:
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
| +-- BufferError
| +-- ArithmeticError
| | +-- FloatingPointError
| | +-- OverflowError
| | +-- ZeroDivisionError
| +-- AssertionError
| +-- AttributeError
| +-- EnvironmentError
| | +-- IOError
| | +-- OSError
| | +-- WindowsError (Windows)
| | +-- VMSError (VMS)
| +-- EOFError
| +-- ImportError
| +-- LookupError
| | +-- IndexError
| | +-- KeyError
| +-- MemoryError
| +-- NameError
| | +-- UnboundLocalError
| +-- ReferenceError
| +-- RuntimeError
| | +-- NotImplementedError
| +-- SyntaxError
| | +-- IndentationError
| | +-- TabError
| +-- SystemError
| +-- TypeError
| +-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StopAsyncIteration
+-- ArithmeticError
| +-- FloatingPointError
| +-- OverflowError
| +-- ZeroDivisionError
+-- AssertionError
+-- AttributeError
+-- BufferError
+-- EOFError
+-- ImportError
+-- LookupError
| +-- IndexError
| +-- KeyError
+-- MemoryError
+-- NameError
| +-- UnboundLocalError
+-- OSError
| +-- BlockingIOError
| +-- ChildProcessError
| +-- ConnectionError
| | +-- BrokenPipeError
| | +-- ConnectionAbortedError
| | +-- ConnectionRefusedError
| | +-- ConnectionResetError
| +-- FileExistsError
| +-- FileNotFoundError
| +-- InterruptedError
| +-- IsADirectoryError
| +-- NotADirectoryError
| +-- PermissionError
| +-- ProcessLookupError
| +-- TimeoutError
+-- ReferenceError
+-- RuntimeError
| +-- NotImplementedError
| +-- RecursionError
+-- SyntaxError
| +-- IndentationError
| +-- TabError
+-- SystemError
+-- TypeError
+-- ValueError
| +-- UnicodeError
| +-- UnicodeDecodeError
| +-- UnicodeEncodeError
| +-- UnicodeTranslateError
+-- Warning
+-- DeprecationWarning
+-- PendingDeprecationWarning
+-- RuntimeWarning
+-- SyntaxWarning
+-- UserWarning
+-- FutureWarning
+-- ImportWarning
+-- UnicodeWarning
+-- BytesWarning
+-- ResourceWarning
अपवाद वस्तुएं भी हैं
अपवाद केवल नियमित पायथन ऑब्जेक्ट हैं जो अंतर्निहित BaseException
से प्राप्त BaseException
। एक अजगर स्क्रिप्ट का उपयोग कर सकते हैं raise
, बाधा निष्पादन के लिए बयान उस बिंदु पर कॉल स्टैक और अपवाद उदाहरण का प्रतिनिधित्व का एक स्टैक ट्रेस मुद्रित करने के लिए अजगर के कारण। उदाहरण के लिए:
>>> def failing_function():
... raise ValueError('Example error!')
>>> failing_function()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in failing_function
ValueError: Example error!
जो कहता है कि एक ValueError
संदेश के साथ 'Example error!'
हमारी failing_function()
द्वारा उठाया गया था, जिसे दुभाषिया में निष्पादित किया गया था।
कॉलिंग कोड किसी भी और सभी प्रकार के अपवादों को संभालना चुन सकता है जो एक कॉल उठा सकते हैं:
>>> try:
... failing_function()
... except ValueError:
... print('Handled the error')
Handled the error
आप अपवाद ऑब्जेक्ट्स को अपवाद में उन्हें असाइन करके प्राप्त कर सकते हैं except...
अपवाद हैंडलिंग कोड का हिस्सा:
>>> try:
... failing_function()
... except ValueError as e:
... print('Caught exception', repr(e))
Caught exception ValueError('Example error!',)
उनके वर्णन के साथ बिल्ट-इन पायथन अपवादों की एक पूरी सूची पायथन डॉक्यूमेंटेशन: https://docs.python.org/3.5/library/exception.html में देखी जा सकती है। और यहाँ पूरी सूची को पदानुक्रम से व्यवस्थित किया गया है: अपवाद पदानुक्रम ।
कस्टम अपवाद प्रकार बनाना
Exception
से विरासत में मिली कक्षा बनाएँ:
class FooException(Exception):
pass
try:
raise FooException("insert description here")
except FooException:
print("A FooException was raised.")
या अन्य अपवाद प्रकार:
class NegativeError(ValueError):
pass
def foo(x):
# function that only accepts positive values of x
if x < 0:
raise NegativeError("Cannot process negative numbers")
... # rest of function body
try:
result = foo(int(input("Enter a positive integer: "))) # raw_input in Python 2.x
except NegativeError:
print("You entered a negative number!")
else:
print("The result was " + str(result))
सब कुछ मत पकड़ो!
हालांकि यह अक्सर हर Exception
को पकड़ने के लिए Exception
:
try:
very_difficult_function()
except Exception:
# log / try to reconnect / exit gratiously
finally:
print "The END"
# it runs no matter what execute.
या यहां तक कि सब कुछ (जिसमें शामिल BaseException
और सहित अपने सभी बच्चों के Exception
):
try:
even_more_difficult_function()
except:
pass # do whatever needed
ज्यादातर मामलों में यह बुरा अभ्यास है। यह अपेक्षा से अधिक पकड़ सकता है, जैसे कि SystemExit
, KeyboardInterrupt
और MemoryError
- जिनमें से प्रत्येक को आम तौर पर सामान्य प्रणाली या तर्क त्रुटियों की तुलना में अलग तरीके से नियंत्रित किया जाना चाहिए। इसका मतलब यह भी है कि आंतरिक कोड क्या गलत कर सकता है और उस स्थिति से ठीक से कैसे उबर सकता है, इसके लिए कोई स्पष्ट समझ नहीं है। यदि आप हर त्रुटि को पकड़ रहे हैं, तो आप नहीं जानते कि क्या त्रुटि हुई या इसे कैसे ठीक किया जाए।
इसे आमतौर पर 'बग मास्किंग' के रूप में संदर्भित किया जाता है और इसे टाला जाना चाहिए। अपने कार्यक्रम को मौन रूप से विफल होने या इससे भी बदतर होने के बजाय, निष्पादन के गहरे स्तर पर विफल होने दें। (कल्पना करें कि यह एक लेनदेन प्रणाली है)
आमतौर पर इन निर्माणों का उपयोग कार्यक्रम के बहुत बाहरी स्तर पर किया जाता है, और त्रुटि के विवरण को लॉग करेगा ताकि बग को ठीक किया जा सके, या त्रुटि को विशेष रूप से नियंत्रित किया जा सके।
कई अपवादों को पकड़ना
कई अपवादों को पकड़ने के लिए कुछ तरीके हैं ।
पहला अपवाद उन प्रकारों का एक समूह बनाकर है जिन्हें आप उसी तरीके से पकड़ना और संभालना चाहते हैं। यह उदाहरण KeyError
और AttributeError
अपवादों को अनदेखा करने के लिए कोड का कारण बनेगा।
try:
d = {}
a = d[1]
b = d.non_existing_field
except (KeyError, AttributeError) as e:
print("A KeyError or an AttributeError exception has been caught.")
यदि आप अलग-अलग तरीकों से अलग-अलग अपवादों को संभालना चाहते हैं, तो आप प्रत्येक प्रकार के लिए एक अलग अपवाद ब्लॉक प्रदान कर सकते हैं। इस उदाहरण में, हम अभी भी KeyError
और AttributeError
पकड़ते हैं, लेकिन विभिन्न मैनर्स में अपवादों को संभालते हैं।
try:
d = {}
a = d[1]
b = d.non_existing_field
except KeyError as e:
print("A KeyError has occurred. Exception message:", e)
except AttributeError as e:
print("An AttributeError has occurred. Exception message:", e)
अपवाद से निपटने के व्यावहारिक उदाहरण
उपयोगकर्ता का निवेश
कल्पना कीजिए कि आप एक उपयोगकर्ता को input
माध्यम से एक नंबर दर्ज करना चाहते हैं। आप यह सुनिश्चित करना चाहते हैं कि इनपुट एक संख्या है। आप except
try
/ उपयोग कर सकते हैं:
while True:
try:
nb = int(input('Enter a number: '))
break
except ValueError:
print('This is not a number, try again.')
नोट: पायथन 2.x इसके बजाय raw_input
उपयोग raw_input
; पायथन 2.x में फ़ंक्शन input
मौजूद है, लेकिन अलग-अलग शब्दार्थ हैं। उपरोक्त उदाहरण में, input
2 + 2
जैसे भावों को भी स्वीकार करेगा जो एक संख्या का मूल्यांकन करते हैं।
यदि इनपुट को पूर्णांक में परिवर्तित नहीं किया जा सकता है, तो ValueError
उठाया जाता है। आप इसे except
पकड़ सकते हैं। कोई अपवाद नहीं उठाया जाता है, तो break
लूप से बाहर कूदता है। लूप के बाद, nb
में एक पूर्णांक होता है।
शब्दकोश
कल्पना कीजिए कि आप लगातार पूर्णांकों की एक सूची से अधिक बार-बार दोहराना कर रहे हैं, जैसे range(n)
, और आप शब्दकोशों की एक सूची है d
है कि जब आप कुछ विशेष पूर्णांकों सामना करते हैं, को छोड़ करने के लिए कहते हैं कि चीजों के बारे में जानकारी शामिल है d[i]
अगले वाले।
d = [{7: 3}, {25: 9}, {38: 5}]
for i in range(len(d)):
do_stuff(i)
try:
dic = d[i]
i += dic[i]
except KeyError:
i += 1
जब आप मौजूद नहीं हैं तो कुंजी के लिए शब्दकोश से मान प्राप्त करने का प्रयास करते समय एक KeyError
को उठाया जाएगा।
अन्य
किसी अन्य ब्लॉक में कोड केवल तभी चलाया जाएगा जब कोई भी try
कोड में कोड द्वारा नहीं उठाए गए थे। यह उपयोगी है यदि आपके पास कोई कोड है जिसे आप चलाना नहीं चाहते हैं यदि कोई अपवाद फेंका गया है, लेकिन आप नहीं चाहते कि उस कोड द्वारा फेंके गए अपवाद को पकड़ा जाए।
उदाहरण के लिए:
try:
data = {1: 'one', 2: 'two'}
print(data[1])
except KeyError as e:
print('key not found')
else:
raise ValueError()
# Output: one
# Output: ValueError
ध्यान दें कि इस तरह का else:
एक के साथ संयुक्त नहीं किया जा सकता if
एक के लिए और कुछ-खंड शुरू करने elif
। आप एक के बाद है, तो if
यह है कि नीचे होते रहने की जरूरत है else:
:
try:
...
except ...:
...
else:
if ...:
...
elif ...:
...
else:
...