Xử lý ngoại lệ (Exception Handling) trong Python



Exception là gì?

Ngoại lệ có thể là bất kỳ điều kiện bất thường nào trong chương trình mà phá vỡ luồng thực thi chương trình đó. Bất cứ khi nào một ngoại lệ xuất hiện, mà không được xử lý, thì chương trình ngừng thực thi và vì thế code không được thực thi.

Python đã định nghĩa sẵn rất nhiều ngoại lệ, mà đã được trình bày trong chương Standard Exception. Trong chương này chúng ta sẽ tìm hiểu cách xử lý ngoại lệ cũng như cách tạo các Custom Exception như thế nào.

Xử lý ngoại lệ trong Python

Nếu bạn thấy bất cứ code nào là khả nghi (có thể gây ra ngoại lệ) thì bạn có thể phòng thủ chương trình của mình bằng cách đặt các khối code khả nghi này trong một khối try. Khối try này được theo sau bởi lệnh except. Sau đó, nó được theo sau bởi các lệnh mà xử lý vấn đề đó.

Cú pháp

Dưới đây là cú pháp của khối try....except...else trong Python:

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ......................
except ExceptionI:
   Neu co ExceptionI, thi thuc thi khoi code nay
except ExceptionII:
   Neu co ExceptionII, thi thuc thi khoi code nay
   ......................
else:
   Neu khong co exception nao thi thuc thi khoi code nay 

Dưới đây là một số điểm bạn cần lưu ý:

  • Phần code khả nghi mà có khả năng tạo exception cần được bao quanh trong khối try.

  • Khối try được theo sau bởi lệnh except. Có thể có một hoặc nhiều lệnh except với một khối try đơn.

  • Lệnh except xác định exception mà xảy ra. Trong trường hợp mà exception đó xảy ra, thì lệnh tương ứng được thực thi.

  • Ở cuối khối try, bạn có thể cung cấp lệnh else. Nó được thực thi khi không có exception nào xảy ra. Khối else là địa điểm tốt cho code mà không cần sự bảo vệ của khối try.

Ví dụ

Ví dụ sau mở một file, ghi nội dung vào file này và sau đó đóng file, tất cả hoạt động đều thành công:

 

try:
   fh = open("testfile", "w")
   fh.write("Day la mot kiem tra nho ve xu ly ngoai le!!")
except IOError:
   print "Error: Khong tim thay file"
else:
   print "Thanh cong ghi noi dung vao file"
   fh.close()

Kết quả là:

Thanh cong ghi noi dung vao file

Ví dụ

Ví dụ sau mở một file để ghi trong khi bạn không có quyền ghi, do đó nó sẽ tạo một exception:

 

try:
   fh = open("testfile", "r")
   fh.write("Day la mot kiem tra nho ve xu ly ngoai le!!")
except IOError:
   print "Error: Khong tim thay file"
else:
   print "Thanh cong ghi noi dung vao file"

Kết quả là:

Error: Khong tim thay file

Mệnh đề except mà không xác định Exception trong Python

Lệnh except cũng có thể được sử dụng mà không xác định exception nào. Lệnh try-except này bắt tất cả exception mà xuất hiện. Sử dụng loại lệnh try-except này không phải là sự thực hành lập trình tốt, bởi vì nó bắt tất cả exception nhưng không làm cho lập trình viên biết được căn nguyên của vấn đề làm xuất hiện exception đó.

Cú pháp

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ......................
except:
   Neu co bat ky exception nao, thi thuc thi khoi code nay
   ......................
else:
   Neu khong co exception nao, thi thuc thi khoi code nay 

Mệnh đề except với nhiều exception trong Python

Sử dụng cùng lệnh except như trên, bạn có thể khai báo nhiều exception như sau:

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   Neu co bat ky exeption nao trong danh sach, 
   thi thuc thi khoi code nay
   ......................
else:
   Neu khong co exception nao, thi thuc thi khoi code nay 

Khối try-finally trong Python

Trong trường hợp nếu có bất kỳ code nào mà người dùng muốn được thực thi, dù cho có xuất hiện exception hay không thì khối code đó có thể được đặt trong khối finally. Khối finally sẽ luôn luôn được thực thi bất chấp có hay không exception. Cú pháp của khối try-finally là:

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ......................
   Do co exeption nen khoi nay bi bo qua
finally:
   Khoi nay nen duoc thuc thi
   ......................

Ghi chú: Bạn có thể cung cấp một hoặc nhiều mệnh đề except, hoặc một mệnh đề finally, nhưng không được cung cấp cả hai. Ngoài ra bạn cũng không thể sử dụng mệnh đề else với một mệnh đề finally.

Ví dụ

 

try:
   fh = open("testfile", "w")
   fh.write("Day la mot kiem tra nho ve xu ly ngoai le!!")
finally:
   print "Error: Khong tim thay file"

Nếu bạn không có quyền mở file trong chế độ ghi, thì code trên sẽ cho kết quả:

Error: Khong tim thay file

Ví dụ trên có thể được viết rõ ràng hơn như sau:

 

try:
   fh = open("testfile", "w")
   try:
      fh.write("Day la mot kiem tra nho ve xu ly ngoai le!!")
   finally:
      print "Chuan bi dong file"
      fh.close()
except IOError:
   print "Error: Khong tim thay file"

Khi một exception được ném trong khối try, thì trình thực thi ngay lập tức truyền tới khối finally. Sau đó tất cả các lệnh trong khối finally được thực thi, exception được tạo lại lần nữa và được xử lý bởi lệnh except nếu có mặt trong lớp trên tiếp theo của lệnh try-except.

Tham số của một Exception trong Python

Một Exception có thể có một tham số, mà là một giá trị mà cung cấp thông tin bổ sung về vấn đề. Nội dung của tham số là đa dạng tùy vào các exception. Dưới đây là cú pháp:

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ......................
except Kieu_exception, Tham_so:
   Ban co the in gia tri cua Tham_so tai day...

Nếu bạn viết code trên để xử lý một exception đơn, bạn có thể có một biến theo sau tên của exception trong lệnh except. Nếu bạn đang khai báo nhiều exception thì bạn có một biến theo sau tuple của các exception đó.

Ví dụ

Ví dụ của một exception đơn:

 

# Dinh nghia mot ham o day.
def temp_convert(var):
   try:
      return int(var)
   except ValueError, Argument:
      print "Tham so khong chua cac so\n", Argument

# Goi ham tren.
temp_convert("xyz");

Tạo một Exception trong Python

Bạn có thể ném tường minh một Exception trong Python bởi sử dụng lệnh raise. Cú pháp của lệnh raise như sau:

raise [Exception [, args ]]

Ở đây, Lop_Exception là kiểu của exception và tham số value (tùy ý) là một giá trị. Để truy cập giá trị này thì từ khóa as được sử dụng.

Ví dụ

try:
    a=10
    print a
    raise NameError("Hello")
except NameError as e:
		print "Mot Exception xuat hien"
		print e

Trong ví dụ trên, e được sử dụng như là một biến tham chiếu mà lưu trữ giá trị của exception.

Ghi chú: để bắt một exception, một mệnh đề except phải tham chiếu tới cùng exception đã được ném. Ví dụ, để bắt exception trên, chúng ta phải viết mệnh đề except như sau:

try:
   Ban thuc hien cac hoat dong cua minh tai day;
   Va day la phan code co the tao exception;
   ...
except "Invalid level!":
   Xu ly ngoai le o day...
else:
   Phan con lai cua code...

Custom Exception trong Python

Python cho phép bạn tạo riêng cho mình các exception bằng cách kế thừa các lớp từ các Standard Exception.

Ví dụ dưới đây liên quan tới RuntimeError. Ở đây, một lớp đã tạo là lớp con của của RuntimeError. Trong khối try, exception được định nghĩa bởi người dùng được tạo và được bắt trong khối except. Biến e được sử dụng để tạo một instance của lớp Networkerror.

class Networkerror(RuntimeError):
   def __init__(self, arg):
      self.args = arg

Sau khi định nghĩa lớp trên, bạn có thể tạo exception như sau:

try:
   raise Networkerror("Bad hostname")
except Networkerror,e:
   print e.args