Điện thoại/ Zalo
0389934723
Bài 16: Exception trong Python
Bất kỳ một ngôn ngữ lập trình nào cũng có phần xử lý lỗi ngoại lệ exception, nó không chỉ giúp cũng ta debug mà còn giúp chúng ta tắt các thông báo lỗi không mong muốn của trương trình khi nó ở chế độ production.
1, Exception trong Python.
Giả sử mình có một hàm sum
như sau:
def sum(a, b):
return a / b
Bây giờ mình sẽ gọi nó như bình thường
print(sum(6,2))
#kết quả: 3
Nhưng trong trường hợp tham số thứ 2 bây giờ không phải bằng 2 nữa mà là bằng 0 thì sao nhỉ.
print(sum(6, 0))
Và đây là kết quả mình thu được:
File ".main.py", line 3, in
print(sum(6, 0))
File ".main.py", line 2, in sum
return a / b
ZeroDivisionError: division by zero
Như các bạn đã thấy thì chương trình đã báo lỗi là không thể thực hiện phép chia cho 0. Và trong trường hợp này thì các bạn có thể hạn chế lỗi bằng cách ràng buộc tham số b sao cho nó khác 0 -> cách này ai cũng biết rồi.
Nhưng ở phạm vị bài này mình muốn hướng dẫn mọi người một cách nữa đó là sử dụng exception.
Để sử dụng exception trong Python thì các bạn sử dụng lệnh try except
theo cú pháp sau:
try:
# code
except exceptionName:
# code
Trong đó:
exceptionName
là tên của các exception mà bạn muốn bắt và xử lý (xem các exception ở phần 2).
Nếu khối lệnh trong try
có 1 lỗi gì đó xảy ra thì chương trình sẽ tìm đến các except phía dưới và nếu một except nào thỏa mãn thì nó sẽ thực thi code trong khối except đó.
VD: Mình sẽ hạn bắt lỗi của ví dụ trên bằng exception.
Như các bạn đã thấy ở dòng báo lỗi trong ví dụ trên nó có đoạn ZeroDivisionError:...
thì ở đây nếu như chúng ta không biết hết các exception trong Python thì có thể dựa vào dòng lỗi đó và bắt theo, trong trường hợp này exception được gọi chính là ZeroDivisionError.
def sum(a, b):
return a / b
try :
print(sum(6, 0))
except ZeroDivisionError:
print('Co loi xay ra!')
#ket qua: Co loi xay ra!
Và đối với mỗi khối lệnh except
thì bạn cũng có thể bắt nhiều excetion trên một lần khai báo. Bằng việc đặt các exception cách nhau bở một dấu ,
VD: Bắt nhiều exception trên một lần khai báo.
try :
# code
except (ZeroDivisionError, RuntimeError):
# code
Hoặc bạn cũng có thể khai báo nhiều except trong một khối lệnh try except
.
VD: Bắt nhiều exception.
try :
# code
except ZeroDivisionError:
# code
except RuntimeError:
# code
Và đương nhiên bạn cũng có thể lồng các khối try except
lại với nhau:
VD:
try :
# code
except ZeroDivisionError:
try :
# code
except StandardError:
# code
except RuntimeError:
# code
2, Finally.
Nếu như trong khối lệnh try except
bạn muốn sẽ có 1 đoạn lệnh chắc chắn sẽ được thực thi cho dù try đúng hay sai, thì bạn sẽ phải khai báo thêm khối lệnh finally
vào cuối khối lệnh try except
theo cú pháp sau:
try:
# code
except:
# code
finally:
# code
Finally trong Python thường được dùng để clear data mà trong quá trình try except
tạo ra.
VD:
def sum(a, b):
return a / b
try:
print(sum(6, 0))
except ZeroDivisionError:
print('Co loi xay ra!')
finally:
print('finally duoc goi!')
# Ket qua:
# Co loi xay ra!
# finally duoc goi!
3, Các exception có sẵn trong Python.
Dưới đây là danh sách các exception mặc định trong Python.
Exception Name | Chú Thích |
Exception | Đây là lớp cơ sở cho tất cả các exception, nó sẽ xuất hiện khi có bất cứ một lỗi nào xảy ra. |
StopIteration | Xuất hiện khi phương thức next() của interator không trỏ đến một đối tượng nào. |
SystemExit | Xuất hiện khi dùng phương thức sys.exit() |
StandardError | Lớp cơ sở cho tất cả các exception. |
ArithmeticError | Xuất hiện khi có lỗi tính toán giữa các số với nhau |
OverflowError | Xuất hiện khi thực hiện tính toán và giá trị của nó vượt quá ngưỡng giới hạn cho phép của kiểu dữ liệu. |
FloatingPointError | Xuất hiện khi tính toán float thất bại. |
ZeroDivisonError | Xuất hiện khi thực hiện phép chia cho 0. |
AssertionError | Xuất hiện trong trường hợp lệnh assert thất bại. |
AttributeError | Xuất hiện khi không tồn tại thuộc tính này, hoặc thiếu tham số truyền vào nó. |
EOFError | Xuất hiện khi không có dữ liệu từ hàm input() hoặc cuối file. |
ImportError | Xuất hiện khi lệnh import thất bại. |
KeyboardInterrupt | Xuất hiện khi ngắt trình biên dịch. |
LookupError | Lớp cơ sở cho tất cả các lỗi về lookup. |
IndexError | Xuất hiện khi index không tồn tại trong list, string,… |
KeyError | Xuất hiện khi key không tồn tại trong dictionary. |
NameError | Xuất hiện khi một biến không tồn tại trong phạm vi bạn gọi nó. |
EnvironmentError | Xuất hiện khi có bất kỳ một lỗi nào ngoài phạm vị của Python. |
IOError | Xuất hiện khi xử dụng input/ output thất bại, hoặc mở file không thành công. |
OSError | Xuất hiện khi có lỗi từ hệ điều hành. |
SyntaxError | Xuất hiện khi chương trình có lỗi cú pháp. |
IndentationError | Xuất hiện khi bạn thụt dòng không đúng. |
SystemError | Xuất hiện khi trình biên dịch có vấn đề nhưng mà nó lại không tự động exit. |
SystemExit | Xuất hiện khi trình biên dịch được thoát bởi sys.exit() . |
TypeError | Xuất hiện khi thực thi toán tử hoặc hàm mà kiểu dữ liệu bị sai so với kiểu dữ liệu đã định nghĩa ban đầu. |
ValueError | Xuất hiện khi chúng ta build 1 function mà kiểu dữ liệu đúng nhưng khi chúng ta thiết lập ở tham số là khác so với khi truyền vào. |
RuntimeError | Xuất hiện khi lỗi được sinh ra không thuộc một danh mục nào. |
NotImplementedError | Xuất hiện khi một phương thức trừu tượng cần được thực hiện trong lớp kế thừa chứ không phải là lớp thực thi |
UnboundLocalError | Xuất hiện khi chúng ta cố tình truy cập vào một biến trong hàm hoặc phương thức, nhưng không thiết lập giá trị cho nó. |
4, Xây dựng một exception riêng.
Do mình chưa giới thiệu với mọi người kiến thức hướng đối tượng trong Python, nên phần này những ai biết hướng đối tượng rồi thì xem, còn không thì khi khác xem lại cũng được :D.
Để tạo một exception trong Python thì bắt buộc exception này phải kế thừa lớp Exception trong Python, và còn lại là bạn muốn xử lý như thế nào cũng được.
VD: Mình sẽ viết một Exception có tên exceptionDemo.
class ExceptionDemo(Exception):
def __init__(self, value):
print("Loi: " + value)
Sau khi đã tạo ra được exception cho riêng mình rồi, thì khi thực hiện mà bạn muốn gọi ra gọi exception ra bạn chỉ cần sử dụng keyword raise
theo cú pháp sau:
raise exceptionName
Trong đó, exceptionName
là tên của exception bạn muốn gọi.
VD:
class ExceptionDemo(Exception):
def __init__(self, value):
print("Loi: " + value)
def sum(a, b):
if (b == 0):
raise ExceptionDemo('b phai khac 0')
return a / b
sum(6, 0)
5, Lời kết.
Phần này hơi dài, nhưng các bạn hay làm ở tầm application thì cũng không cần phải quan tâm lắm, vì các framework đã hỗ trợ chúng ta phần này khá là ok rồi.