Các lớp ngoại lệ và ngoại lệ
Nói chung, một ngoại lệ là bất kỳ tình trạng bất thường nào. Ngoại lệ thường chỉ ra lỗi nhưng đôi khi chúng cố ý đưa vào chương trình, trong các trường hợp như kết thúc sớm một thủ tục hoặc khôi phục sau khi thiếu tài nguyên. Có một số ngoại lệ được tích hợp sẵn, cho biết các điều kiện như đọc quá cuối tệp hoặc chia cho số không. Chúng tôi có thể xác định các ngoại lệ của riêng mình được gọi là ngoại lệ tùy chỉnh.
Xử lý ngoại lệ cho phép bạn xử lý lỗi một cách duyên dáng và làm điều gì đó có ý nghĩa với nó. Xử lý ngoại lệ có hai thành phần: "ném" và "bắt".
Xác định Ngoại lệ (Lỗi)
Mọi lỗi xảy ra trong Python đều dẫn đến một ngoại lệ sẽ là một điều kiện lỗi được xác định bởi loại lỗi của nó.
>>> #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.
Ngoại lệ bắt / bẫy
Khi có điều gì đó bất thường xảy ra trong chương trình của bạn và bạn muốn xử lý nó bằng cơ chế ngoại lệ, bạn 'ném một ngoại lệ'. Các từ khóa try và ngoại trừ được sử dụng để bắt các ngoại lệ. Bất cứ khi nào có lỗi xảy ra trong một khối thử, Python sẽ tìm một khối ngoại trừ phù hợp để xử lý nó. Nếu có một, quá trình thực thi sẽ nhảy ở đó.
cú pháp
try:
#write some code
#that might throw some exception
except <ExceptionType>:
# Exception handler, alert the user
Đoạn mã trong mệnh đề try sẽ được thực thi từng câu lệnh.
Nếu một ngoại lệ xảy ra, phần còn lại của khối try sẽ bị bỏ qua và mệnh đề Ngoại trừ sẽ được thực thi.
try:
some statement here
except:
exception handling
Hãy viết một số mã để xem điều gì sẽ xảy ra khi bạn không sử dụng bất kỳ cơ chế xử lý lỗi nào trong chương trình của mình.
number = int(input('Please enter the number between 1 & 10: '))
print('You have entered number',number)
Chương trình trên sẽ hoạt động chính xác miễn là người dùng nhập một số, nhưng điều gì sẽ xảy ra nếu người dùng cố gắng đặt một số kiểu dữ liệu khác (như chuỗi hoặc danh sách).
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'"
Bây giờ ValueError là một loại ngoại lệ. Hãy thử viết lại đoạn mã trên với xử lý ngoại lệ.
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)
Nếu chúng ta chạy chương trình và nhập một chuỗi (thay vì một số), chúng ta có thể thấy rằng chúng ta nhận được một kết quả khác.
Previous code with exception handling
Enter number between 1 > 10: 'Hi'
Error..numbers only
Nâng cao ngoại lệ
Để nâng cao các ngoại lệ của bạn từ các phương pháp của riêng bạn, bạn cần sử dụng từ khóa raise như thế này
raise ExceptionClass(‘Some Text Here’)
Hãy lấy một ví dụ
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')
Chạy chương trình và nhập số nguyên dương.
Sản lượng mong đợi
Enter your age: 12
Entered Age is even
Nhưng khi cố gắng nhập một số âm, chúng tôi nhận được,
Sản lượng mong đợi
Enter your age: -2
Only positive integers are allowed
Tạo lớp ngoại lệ tùy chỉnh
Bạn có thể tạo một lớp ngoại lệ tùy chỉnh bằng cách Mở rộng lớp BaseException hoặc lớp con của BaseException.
Từ sơ đồ trên, chúng ta có thể thấy hầu hết các lớp ngoại lệ trong Python đều mở rộng từ lớp BaseException. Bạn có thể lấy lớp ngoại lệ của riêng mình từ lớp BaseException hoặc từ lớp con của nó.
Tạo một tệp mới có tên là NegativeNumberException.py và viết mã sau.
class NegativeNumberException(RuntimeError):
def __init__(self, age):
super().__init__()
self.age = age
Đoạn mã trên tạo ra một lớp ngoại lệ mới có tên là NegativeNumberException, chỉ bao gồm hàm tạo gọi hàm tạo lớp cha bằng cách sử dụng super () __ init __ () và đặt tuổi.
Bây giờ để tạo lớp ngoại lệ tùy chỉnh của riêng bạn, sẽ viết một số mã và nhập lớp ngoại lệ mới.
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')
Đầu ra
Enter your age: -2
Only positive integers are allowed
Một cách khác để tạo một lớp Ngoại lệ tùy chỉnh.
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)
Đầu ra
Caught: My Useful Error Message!
Hệ thống phân cấp ngoại lệ
Hệ thống phân cấp lớp cho các ngoại lệ được tích hợp sẵn là:
+-- 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