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

<p>Trong b&agrave;i viết n&agrave;y, ta sẽ t&igrave;m hiểu về c&aacute;ch xử l&yacute; ngoại lệ (Exception Handling) trong Python bằng c&aacute;ch sử dụng c&acirc;u lệnh try, exception v&agrave; finally c&ugrave;ng với sự trợ gi&uacute;p của c&aacute;c v&iacute; dụ dẫn chứng.</p> <p>Python c&oacute; nhiều ngoại lệ đ&atilde; được t&iacute;ch hợp v&agrave; được đưa ra khi chương tr&igrave;nh gặp lỗi. Khi những ngoại lệ n&agrave;y xảy ra, tr&igrave;nh th&ocirc;ng dịch Python dừng qu&aacute; tr&igrave;nh xử l&yacute; hiện tại v&agrave; chuyển n&oacute; cho qu&aacute; tr&igrave;nh kh&aacute;c cho đến khi n&oacute; được xử l&yacute;. Nếu kh&ocirc;ng được xử l&yacute;, chương tr&igrave;nh sẽ bị dừng lại.</p> <p>V&iacute; dụ, một chương tr&igrave;nh m&agrave; ch&uacute;ng ta c&oacute; một h&agrave;m A gọi h&agrave;m B, h&agrave;m n&agrave;y lần lượt gọi h&agrave;m C. Nếu một ngoại lệ xảy ra trong h&agrave;m C nhưng kh&ocirc;ng được xử l&yacute; trong C, th&igrave; ngoại lệ sẽ chuyển đến B rồi đến A. Nếu kh&ocirc;ng bao giờ được xử l&yacute;, một th&ocirc;ng b&aacute;o lỗi sẽ hiển thị v&agrave; chương tr&igrave;nh bị dừng đột ngột.</p> <h2>1. Xử l&yacute; ngoại lệ bằng Python</h2> <p>Thao t&aacute;c quan trọng c&oacute; thể tạo ra một ngoại lệ được đặt b&ecirc;n trong mệnh đề try. Đoạn m&atilde; xử l&yacute; c&aacute;c ngoại lệ được viết trong mệnh đề exception. Do đ&oacute;, ch&uacute;ng ta c&oacute; thể chọn những thao t&aacute;c để thực hiện khi ch&uacute;ng ta đ&atilde; xử l&yacute; được ngoại lệ.</p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>import sys try: a = 1 / 0 except: print("Ngoại lệ xảy ra l&agrave;:", sys.exc_info()[0])</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Ngoại lệ xảy ra l&agrave;: &lt;class 'ZeroDivisionError'&gt;</code></pre> <p>Trong chương tr&igrave;nh n&agrave;y, ch&uacute;ng ta sẽ thực hiện ph&eacute;p chia cho gi&aacute; trị l&agrave; 0. Như đ&atilde; đề cập trước đ&acirc;y, phần c&oacute; thể g&acirc;y ra ngoại lệ được đặt b&ecirc;n trong khối try. Nếu kh&ocirc;ng c&oacute; ngoại lệ n&agrave;o xảy ra, khối exception sẽ bị bỏ qua v&agrave; luồng thực thi được tiếp tục hoạt động. Nhưng nếu bất kỳ ngoại lệ n&agrave;o xảy ra, n&oacute; sẽ bị chặn bởi khối exception.</p> <p>Ở đ&acirc;y, ch&uacute;ng ta đ&atilde; in t&ecirc;n của ngoại lệ bằng c&aacute;ch sử dụng h&agrave;m <code class="EnlighterJSRAW" data-enlighter-language="generic">exc_info()</code>b&ecirc;n trong m&ocirc;-đun sys. V&igrave; mọi ngoại lệ trong Python đều kế thừa từ lớp Exception cơ sở, ch&uacute;ng ta cũng c&oacute; thể thực hiện theo c&aacute;ch sau.</p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>import sys try: a = 1 / 0 except Exception as e: print("Ngoại lệ xảy ra l&agrave;:", e.__class__)</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Ngoại lệ xảy ra l&agrave;: &lt;class 'ZeroDivisionError'&gt;</code></pre> <h2>2. Xử l&yacute; c&aacute;c ngoại lệ cụ thể trong Python</h2> <p>Trong v&iacute; dụ tr&ecirc;n, ch&uacute;ng ta đ&atilde; kh&ocirc;ng đề cập đến bất kỳ ngoại lệ cụ thể n&agrave;o trong mệnh đề exception. Đ&acirc;y kh&ocirc;ng phải l&agrave; một phương ph&aacute;p lập tr&igrave;nh tốt v&igrave; n&oacute; sẽ bắt tất cả c&aacute;c ngoại lệ v&agrave; xử l&yacute; mọi trường hợp theo c&ugrave;ng một c&aacute;ch. Ch&uacute;ng ta c&oacute; thể chỉ định ngoại lệ n&agrave;o m&agrave; mệnh đề exception sẽ xử l&yacute;.</p> <p>Một mệnh đề try c&oacute; thể c&oacute; bất kỳ số mệnh đề exception n&agrave;o để xử l&yacute; c&aacute;c ngoại lệ kh&aacute;c nhau, tuy nhi&ecirc;n, chỉ một mệnh đề sẽ được thực thi trong trường hợp một ngoại lệ nhất định xảy ra. Ch&uacute;ng ta c&oacute; thể sử dụng một bộ gi&aacute; trị để chỉ định nhiều ngoại lệ trong một mệnh đề exception.</p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>try: a = 1 / 0 except ZeroDivisionError: print("Lỗi 1 xảy ra") except (IndentationError, UnicodeError): print("Lỗi 2 xảy ra") except: print("C&aacute;c lỗi c&ograve;n lại xảy ra")</code></pre> <h2>3. Đưa ra ngoại lệ trong Python</h2> <p>Trong lập tr&igrave;nh Python, c&aacute;c ngoại lệ được đưa ra khi lỗi xảy ra trong thời gian thực thi. Ch&uacute;ng ta cũng c&oacute; thể đưa ra c&aacute;c ngoại lệ theo c&aacute;ch thủ c&ocirc;ng bằng c&aacute;ch sử dụng từ kh&oacute;a <code class="EnlighterJSRAW" data-enlighter-language="generic">raise</code>.</p> <p>Ch&uacute;ng ta c&oacute; thể t&ugrave;y chọn truyền c&aacute;c gi&aacute; trị cho ngoại lệ để l&agrave;m r&otilde; l&yacute; do tại sao ngoại lệ đ&oacute; được đưa ra.</p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>raise KeyboardInterrupt("Lỗi xảy ra v&igrave; ...")</code></pre> <h2>4. Sử dụng khối try với mệnh đề else</h2> <p>Trong một số t&igrave;nh huống, ta c&oacute; thể muốn chạy một khối đoạn m&atilde; nhất định nếu khối đoạn m&atilde; b&ecirc;n trong try chạy m&agrave; kh&ocirc;ng c&oacute; bất kỳ lỗi n&agrave;o xảy ra. Đối với những trường hợp n&agrave;y, ta c&oacute; thể sử dụng từ kh&oacute;a else với c&acirc;u lệnh try.</p> <p><strong>Ch&uacute; &yacute;: C&aacute;c ngoại lệ trong mệnh đề else kh&ocirc;ng được xử l&yacute; bởi c&aacute;c mệnh đề exception trước đ&oacute;.</strong></p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>try: a = 1 / 3 except: print("Sai!") else: b = 1 / 0 print(b)</code></pre> <h2>5. Khối try v&agrave; finally trong Python</h2> <p>C&acirc;u lệnh try trong Python c&oacute; thể c&oacute; mệnh đề finally t&ugrave;y chọn. Mệnh đề n&agrave;y được thực thi bất kể lỗi xảy ra hay kh&ocirc;ng, v&agrave; thường được sử dụng để giải ph&oacute;ng c&aacute;c t&agrave;i nguy&ecirc;n b&ecirc;n ngo&agrave;i.</p> <p>V&iacute; dụ: Ch&uacute;ng ta c&oacute; thể được kết nối với trung t&acirc;m dữ liệu từ xa th&ocirc;ng qua mạng hoặc l&agrave;m việc với tệp.</p> <p>Trong tất cả c&aacute;c trường hợp n&agrave;y, ch&uacute;ng ta phải giải ph&oacute;ng t&agrave;i nguy&ecirc;n trước khi chương tr&igrave;nh tạm dừng cho d&ugrave; n&oacute; c&oacute; chạy th&agrave;nh c&ocirc;ng hay kh&ocirc;ng. Những h&agrave;nh động v&iacute; dụ như đ&oacute;ng tệp để giải ph&oacute;ng t&agrave;i nguy&ecirc;n phải được thực hiện trong mệnh đề finally để đảm bảo việc thực thi.</p> <p>V&iacute; dụ:</p> <pre class="language-python"><code>try: file = open("tek4.txt",encoding = 'utf-8') finally: file.close()</code></pre> <p>Loại cấu tr&uacute;c n&agrave;y đảm bảo rằng tệp được đ&oacute;ng ngay cả khi một ngoại lệ xảy ra trong qu&aacute; tr&igrave;nh thực thi chương tr&igrave;nh.</p> <p>V&iacute; dụ 2:</p> <pre class="language-python"><code>try: a = 1 / 0 except: print("Lỗi xảy ra") finally: print("Chương tr&igrave;nh thực hiện xong")</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Lỗi xảy ra Chương tr&igrave;nh thực hiện xong</code></pre> <p>Tr&ecirc;n đ&acirc;y l&agrave; kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về c&aacute;ch xử l&yacute; ngoại lệ (Exception Handling) trong Python. Hy vọng mọi người c&oacute; thể &aacute;p dụng v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i tiếp theo về lập tr&igrave;nh Python tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p>