Bài 9: Xử lý lỗi với try/except trong Python

Bài 8 bạn đã gói hành động vào hàm. Nhưng chương trình thật luôn gặp tình huống ngoài ý muốn: người dùng gõ chữ khi cần số, file không tồn tại, chia cho 0… Nếu không xử lý, chương trình sập với thông báo lỗi khó hiểu. Bài này dạy try/except — cách bắt lỗi để chương trình chạy êm và báo lỗi thân thiện. Cuối bài bạn viết một chương trình nhập số an toàn không bao giờ sập.
⏱️ Cách học bài này (~30 phút): đọc try/except (10’), tự gõ và chạy các bài thực hành (12’), xem lỗi thường gặp (4’), tự kiểm + lưu code mang về (4’).
Mục tiêu bài học
Sau bài này bạn sẽ:
- Dùng try/except để bắt lỗi thay vì để chương trình sập.
- Bắt lỗi cụ thể (ValueError, ZeroDivisionError).
- Báo lỗi thân thiện và cho nhập lại.
- Biết else/finally ở mức cơ bản.
Nội dung: try/except
1. Vì sao cần try/except
Không có nó, gõ sai là sập:
tuoi = int(input("Tuổi: ")) # gõ "abc" → ValueError, chương trình DỪNG
Có try/except, chương trình xử lý êm:
try:
tuoi = int(input("Tuổi: "))
print(f"Bạn {tuoi} tuổi.")
except ValueError:
print("Vui lòng nhập một số!") # bắt lỗi, không sập
2. Bắt lỗi cụ thể (nên làm)
Bắt đúng loại lỗi thay vì bắt tất cả:
try:
a = int(input("Số bị chia: "))
b = int(input("Số chia: "))
print(a / b)
except ValueError:
print("Phải nhập số!") # gõ chữ
except ZeroDivisionError:
print("Không chia được cho 0!") # b = 0
⚠️ Tránh
except:trơ (bắt tất cả) vì nó che giấu cả lỗi lập trình thật. Bắt lỗi cụ thể giúp bạn xử lý đúng và dễ debug.
3. Cho nhập lại (kết hợp vòng lặp)
while True:
try:
tuoi = int(input("Nhập tuổi: "))
break # nhập đúng → thoát vòng lặp
except ValueError:
print("Sai rồi, nhập lại một số nguyên.")
4. else và finally (biết là đủ)
try:
so = int(input("Số: "))
except ValueError:
print("Không phải số.")
else:
print(f"Bình phương: {so**2}") # chạy khi KHÔNG lỗi
finally:
print("Đã xử lý xong.") # LUÔN chạy
Code mẫu có chú thích: nhập số an toàn
Hàm nhận số an toàn, không bao giờ sập:
def nhap_so(loi_nhac):
while True:
try:
return float(input(loi_nhac)) # nhập đúng → trả về ngay
except ValueError:
print("⚠️ Vui lòng nhập một số hợp lệ.")
diem = nhap_so("Nhập điểm: ") # gõ "abc" → báo lỗi, hỏi lại; gõ 8 → nhận
print(f"Điểm bạn nhập: {diem}")
Mấu chốt: bọc float(input(...)) trong try, sai thì báo và lặp lại; đúng thì return thoát hàm. Đây là mẫu tái dùng cực nhiều.
⚠️ “Không bao giờ sập” ở đây là với lỗi nhập sai kiểu (ValueError). Vẫn còn ngoại lệ khác như
EOFError/KeyboardInterrupt(nhấn Ctrl+C) không bị bắt — đủ dùng cho người mới.
Bài thực hành code (tự gõ)
Bài 1 — Bắt ValueError: hỏi tuổi bằng int(input()) trong try/except; gõ chữ thì in “Phải nhập số!”.
Bài 2 — Chia an toàn: nhận 2 số rồi in thương; bắt cả ValueError (gõ chữ) và ZeroDivisionError (chia 0).
Bài 3 — Nhập lại tới khi đúng: dùng while True + try/except để bắt người dùng nhập một số nguyên, sai thì hỏi lại.
Lỗi thường gặp & cách sửa
- Dùng
except:trơ → che giấu mọi lỗi kể cả lỗi lập trình. Hãy bắt lỗi cụ thể (except ValueError). - Đặt quá nhiều code trong try → khó biết dòng nào lỗi. Chỉ bọc phần có thể lỗi.
- Quên dấu
:sautry/except→SyntaxError. - Thụt lề sai trong khối try/except →
IndentationError(xem Bài 4). - Muốn hiểu cách đọc thông báo lỗi để biết bắt lỗi nào: xem cách đọc lỗi và debug cho người mới.
💾 Mang về — hàm nhập số an toàn
Lưu vào kho code cá nhân (bài L9 trong series) — dùng lại ở mọi chương trình cần nhập số:
# nhap_an_toan.py — nhập số không bao giờ sập
def nhap_so(loi_nhac):
while True:
try:
return float(input(loi_nhac))
except ValueError:
print("⚠️ Vui lòng nhập một số hợp lệ.")
a = nhap_so("Số thứ nhất: ")
b = nhap_so("Số thứ hai: ")
print(f"Tổng: {a + b}")
Thuật ngữ chốt
| Thuật ngữ | Giải thích ngắn |
|---|---|
| try | Khối chứa code có thể gây lỗi |
| except | Khối xử lý khi có lỗi |
| ValueError | Lỗi khi ép kiểu sai (int(“abc”)) |
| ZeroDivisionError | Lỗi chia cho 0 |
| else (trong try) | Chạy khi try không có lỗi |
| finally | Luôn chạy, dù có lỗi hay không |
Tự kiểm tra & lời giải
int("abc")gây lỗi gì? (Đáp án: ValueError)- Vì sao nên tránh
except:trơ? (Đáp án: nó che giấu cả lỗi lập trình thật, khó debug) - Khối
finallychạy khi nào? (Đáp án: luôn chạy, dù có lỗi hay không)
Lời giải Bài thực hành:
# Bài 1
try:
tuoi = int(input("Tuổi: "))
print(tuoi)
except ValueError:
print("Phải nhập số!")
# Bài 2
try:
a = int(input("a: "))
b = int(input("b: "))
print(a / b)
except ValueError:
print("Phải nhập số!")
except ZeroDivisionError:
print("Không chia cho 0!")
# Bài 3
while True:
try:
n = int(input("Số nguyên: "))
break
except ValueError:
print("Sai, nhập lại.")
print("Bạn nhập:", n)
Ghi nhớ nhanh
- try: đặt code có thể lỗi; except LoạiLỗi: xử lý khi lỗi — chương trình không sập.
- Bắt lỗi cụ thể (ValueError, ZeroDivisionError), tránh
except:trơ. - Mẫu vàng:
while True+ try/except + return để nhập liệu an toàn.
👉 Bài tập về nhà: thêm try/except vào chương trình xếp loại điểm (Bài 4) để nhập điểm sai không làm sập chương trình. Bài tiếp theo trong series: Bài 10 — Đọc & ghi file (sắp đăng).
Câu hỏi thường gặp
try/except trong Python để làm gì?
Để ‘bắt’ lỗi và xử lý thay vì để chương trình sập. Bạn đặt đoạn code có thể lỗi trong khối try; nếu xảy ra lỗi, Python nhảy sang khối except để bạn báo lỗi thân thiện hoặc cho nhập lại. Ví dụ điển hình: người dùng gõ chữ khi bạn cần số — không có try/except thì chương trình dừng đột ngột với thông báo lỗi khó hiểu.
Nên bắt lỗi chung hay lỗi cụ thể?
Nên bắt lỗi CỤ THỂ khi có thể, ví dụ ‘except ValueError:’ cho lỗi ép kiểu, thay vì ‘except:’ bắt tất cả. Bắt lỗi cụ thể giúp bạn xử lý đúng loại vấn đề và không vô tình che giấu các lỗi khác (như lỗi lập trình thật). Bắt chung chỉ nên dùng ở lớp ngoài cùng để chương trình không sập hẳn.
else và finally trong try dùng khi nào?
Khối ‘else’ chạy khi try KHÔNG có lỗi — hợp để đặt phần chỉ nên chạy khi mọi thứ ổn. Khối ‘finally’ luôn chạy dù có lỗi hay không — hợp để dọn dẹp (đóng file, giải phóng tài nguyên). Với người mới, try/except là đủ cho hầu hết trường hợp; else/finally học thêm khi cần.
Thợ code chính hiệu, thích dắt người mới qua mấy đoạn 'khó nhằn' bằng giọng nhẹ tênh. Châm ngôn: cứ làm dự án thật, sai thì sửa, vui là chính.
Bài liên quan

Bài 7: CSS — responsive cho điện thoại
Bài 7 series Web cơ bản (bài học 30 phút): làm trang co giãn đẹp trên điện thoại với thẻ viewport, đơn vị linh hoạt và media query — biến trang cá nhân thành responsive; kèm thực hành và file mang về.

Bài 8: Hàm (function) trong Python
Bài 8 series Python cho người mới (bài học 30 phút): viết hàm để tái sử dụng code — tham số, giá trị trả về, tham số mặc định — qua chương trình quản lý điểm gọn gàng bằng hàm; kèm bài tập và code mang về.

Tự học lập trình từ con số 0: lộ trình cho người mới
Muốn tự học lập trình nhưng không biết bắt đầu từ đâu? Đây là lộ trình từ con số 0 theo từng giai đoạn — chọn ngôn ngữ, học nền tảng, làm dự án, và tránh những cái bẫy khiến người mới bỏ cuộc.