通常,例外是任何異常情況。 例外通常表示錯(cuò)誤,但有時(shí)他們故意放入程序,例如提前終止程序或從資源短缺中恢復(fù)。 有許多內(nèi)置異常,表示讀取文件末尾或除以零等條件。 我們可以定義自己的異常,稱為自定義異常。
異常處理使您可以優(yōu)雅地處理錯(cuò)誤并對(duì)其執(zhí)行有意義的操作。 異常處理有兩個(gè)組成部分:“拋出”和“捕獲”。
Python中發(fā)生的每個(gè)錯(cuò)誤都會(huì)導(dǎo)致異常,這個(gè)異常將由其錯(cuò)誤類型識(shí)別出錯(cuò)誤條件。
>>> #Exception
>>> 1/0
Traceback (most recent call last):
File "<pyshell#2>", line 1, in <module>
1/0
ZeroDivisionError: division by zero
>>>
>>> var = 20
>>> print(ver)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
print(ver)
NameError: name 'ver' is not defined
>>> #Above as we have misspelled a variable name so we get an NameError.
>>>
>>> print('hello)
SyntaxError: EOL while scanning string literal
>>> #Above we have not closed the quote in a string, so we get SyntaxError.
>>>
>>> #Below we are asking for a key, that doen't exists.
>>> mydict = {}
>>> mydict['x']
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
mydict['x']
KeyError: 'x'
>>> #Above keyError
>>>
>>> #Below asking for a index that didn't exist in a list.
>>> mylist = [1,2,3,4]
>>> mylist[5]
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
mylist[5]
IndexError: list index out of range
>>> #Above, index out of range, raised IndexError.
當(dāng)程序中出現(xiàn)異常并且您希望使用異常機(jī)制處理它時(shí),可能需要“拋出異?!?。 關(guān)鍵字try和except用于捕獲異常。 每當(dāng)try塊中發(fā)生錯(cuò)誤時(shí),Python都會(huì)查找匹配的except塊來(lái)處理它。 如果有,執(zhí)行跳轉(zhuǎn)到那里。
try:
#write some code
#that might throw some exception
except <ExceptionType>:
# Exception handler, alert the user
try子句中的代碼將逐語(yǔ)句執(zhí)行。
如果發(fā)生異常,將跳過(guò)try塊的其余部分并執(zhí)行except子句。
try:
some statement here
except:
exception handling
下面編寫(xiě)一些代碼,看看在程序中不使用任何錯(cuò)誤處理機(jī)制時(shí)會(huì)發(fā)生什么。
number = int(input('Please enter the number between 1 & 10: '))
print('You have entered number',number)
只要用戶輸入一個(gè)數(shù)字,上面的程序就能正常工作,但如果用戶試圖放入一些其他數(shù)據(jù)類型(如字符串或列表)會(huì)發(fā)生什么。
Please enter the number between 1 > 10: 'Hi'
Traceback (most recent call last):
File "C:/Python/Python361/exception2.py", line 1, in <module>
number = int(input('Please enter the number between 1 & 10: '))
ValueError: invalid literal for int() with base 10: "'Hi'"
現(xiàn)在ValueError是一種異常類型。下面嘗試用異常處理重寫(xiě)上面的代碼。
import sys
print('Previous code with exception handling')
try:
number = int(input('Enter number between 1 > 10: '))
except(ValueError):
print('Error..numbers only')
sys.exit()
print('You have entered number: ',number)
如果運(yùn)行上面程序,并輸入一個(gè)字符串(而不是數(shù)字),應(yīng)該會(huì)看到不同的結(jié)果。
Previous code with exception handling
Enter number between 1 > 10: 'Hi'
Error..numbers only
要從您自己的方法中引發(fā)異常,需要使用raise關(guān)鍵字 -
raise ExceptionClass('Some Text Here')
看看下面一個(gè)例子 -
def enterAge(age):
if age<0:
raise ValueError('Only positive integers are allowed')
if age % 2 ==0:
print('Entered Age is even')
else:
print('Entered Age is odd')
try:
num = int(input('Enter your age: '))
enterAge(num)
except ValueError:
print('Only positive integers are allowed')
運(yùn)行程序并輸入正整數(shù),應(yīng)該會(huì)得到類似以下的結(jié)果 -
Enter your age: 12
Entered Age is even
但是當(dāng)輸入負(fù)數(shù)時(shí),得到以下結(jié)果 -
Enter your age: -2
Only positive integers are allowed
可以通過(guò)擴(kuò)展BaseException類或BaseException的子類來(lái)創(chuàng)建自定義異常類。

從上圖中可以看到Python中的大多數(shù)異常類都是從BaseException類擴(kuò)展而來(lái)的。可以從BaseException類或其子類派生自己的異常類。
創(chuàng)建一個(gè)名為NegativeNumberException.py的新文件并編寫(xiě)以下代碼。
class NegativeNumberException(RuntimeError):
def __init__(self, age):
super().__init__()
self.age = age
上面的代碼創(chuàng)建了一個(gè)名為NegativeNumberException的新異常類,它只包含使用super().__ init __()調(diào)用父類構(gòu)造函數(shù)的構(gòu)造函數(shù),并設(shè)置年齡。
現(xiàn)在要?jiǎng)?chuàng)建自己的自定義異常類,將編寫(xiě)一些代碼并導(dǎo)入新的異常類。
from NegativeNumberException import NegativeNumberException
def enterage(age):
if age < 0:
raise NegativeNumberException('Only positive integers are allowed')
if age % 2 == 0:
print('Age is Even')
else:
print('Age is Odd')
try:
num = int(input('Enter your age: '))
enterage(num)
except NegativeNumberException:
print('Only positive integers are allowed')
except:
print('Something is wrong')
執(zhí)行上面示例代碼,得到以下結(jié)果 -
Enter your age: -2
Only positive integers are allowed
另一種創(chuàng)建自定義Exception類的方法。
class customException(Exception):
def __init__(self, value):
self.parameter = value
def __str__(self):
return repr(self.parameter)
try:
raise customException('My Useful Error Message!')
except customException as instance:
print('Caught: ' + instance.parameter)
執(zhí)行上面示例代碼,得到以下結(jié)果 -
Caught: My Useful Error Message!
異常層次結(jié)構(gòu)
內(nèi)置異常的類層次結(jié)構(gòu)是 -
+-- 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