Bài 4.2. Tránh lỗi thụt đầu dòng

Bài 4.2. Tránh lỗi thụt đầu dòng
Python sử dụng thụt đầu dòng để xác định cách một dòng hoặc nhóm dòng liên quan đến phần còn lại của chương trình. Trong các ví dụ trước, các dòng in ra thông báo cho từng ảo thuật gia là một phần của vòng lặp for vì chúng được thụt đầu dòng. Việc sử dụng thụt đầu dòng của Python làm cho mã rất dễ đọc. Về cơ bản, nó sử dụng khoảng trắng để buộc bạn viết mã được định dạng gọn gàng với cấu trúc trực quan rõ ràng. Trong các chương trình Python dài hơn, bạn sẽ nhận thấy các khối mã được thụt đầu dòng ở một vài mức độ khác nhau. Các mức thụt đầu dòng này giúp bạn có cái nhìn tổng quan về tổ chức của toàn bộ chương trình.
Khi bạn bắt đầu viết mã dựa vào thụt đầu dòng đúng cách, bạn sẽ cần chú ý đến một số lỗi thụt đầu dòng phổ biến. Ví dụ, mọi người đôi khi thụt đầu dòng các dòng mã không cần thụt đầu dòng hoặc quên thụt đầu dòng các dòng cần thụt đầu dòng. Xem các ví dụ về những lỗi này bây giờ sẽ giúp bạn tránh chúng trong tương lai và sửa chúng khi chúng xuất hiện trong các chương trình của riêng bạn.
Hãy xem xét một số lỗi thụt đầu dòng phổ biến hơn.
Quên thụt đầu dòng
Luôn thụt đầu dòng dòng sau câu lệnh for trong một vòng lặp. Nếu bạn quên, Python sẽ nhắc nhở bạn:
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(magician)
Lệnh gọi print() nên được thụt đầu dòng, nhưng không phải. Khi Python mong đợi một khối thụt đầu dòng và không tìm thấy, nó sẽ cho bạn biết dòng nào gặp vấn đề:
File "magicians.py", line 3
print(magician)
^
IndentationError: expected an indented block after 'for' statement on line 2
Bạn thường có thể giải quyết loại lỗi thụt đầu dòng này bằng cách thụt đầu dòng dòng hoặc các dòng ngay sau câu lệnh for.
Quên thụt đầu dòng các dòng bổ sung
Đôi khi vòng lặp của bạn sẽ chạy mà không có lỗi nhưng không tạo ra kết quả mong đợi. Điều này có thể xảy ra khi bạn đang cố gắng thực hiện một số tác vụ trong một vòng lặp và bạn quên thụt đầu dòng một số dòng của nó.
Ví dụ, đây là những gì xảy ra khi chúng ta quên thụt đầu dòng dòng thứ hai trong vòng lặp nói với mỗi ảo thuật gia rằng chúng ta đang mong chờ trò ảo thuật tiếp theo của họ:
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(f"{magician.title()}, that was a great trick!")
print(f"I can't wait to see your next trick, {magician.title()}.\n")
Lệnh gọi print() thứ hai đáng lẽ phải được thụt đầu dòng, nhưng vì Python tìm thấy ít nhất một dòng thụt đầu dòng sau câu lệnh for, nó không báo lỗi. Kết quả là, lệnh gọi print() đầu tiên được thực thi một lần cho mỗi tên trong danh sách vì nó được thụt đầu dòng. Lệnh gọi print() thứ hai không được thụt đầu dòng, vì vậy nó chỉ được thực thi một lần sau khi vòng lặp đã hoàn thành. Vì giá trị cuối cùng liên kết với magician là 'carolina', cô ấy là người duy nhất nhận được thông báo "mong chờ trò ảo thuật tiếp theo":
Alice, that was a great trick!
David, that was a great trick!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.
Đây là một lỗi logic. Cú pháp là mã Python hợp lệ, nhưng mã không tạo ra kết quả mong muốn vì có vấn đề xảy ra trong logic của nó. Nếu bạn mong đợi thấy một hành động nhất định được lặp lại một lần cho mỗi mục trong danh sách và nó chỉ được thực thi một lần, hãy xác định xem bạn có cần thụt đầu dòng một dòng hoặc một nhóm dòng hay không.
Thụt đầu dòng không cần thiết
Nếu bạn vô tình thụt đầu dòng một dòng không cần thụt đầu dòng, Python sẽ thông báo cho bạn về thụt đầu dòng không mong đợi:
message = "Hello Python world!"
print(message)
Chúng ta không cần thụt đầu dòng lệnh gọi print(), vì nó không phải là một phần của vòng lặp; do đó, Python báo lỗi:
File "hello_world.py", line 2
print(message)
^
IndentationError: unexpected indent
Bạn có thể tránh lỗi thụt đầu dòng không mong đợi bằng cách chỉ thụt đầu dòng khi bạn có lý do cụ thể để làm như vậy. Trong các chương trình bạn đang viết tại thời điểm này, các dòng duy nhất bạn nên thụt đầu dòng là các hành động bạn muốn lặp lại cho mỗi mục trong một vòng lặp for.
Thụt đầu dòng không cần thiết sau vòng lặp
Nếu bạn vô tình thụt đầu dòng mã nên chạy sau khi vòng lặp đã hoàn thành, mã đó sẽ được lặp lại một lần cho mỗi mục trong danh sách. Đôi khi điều này sẽ khiến Python báo lỗi, nhưng thường thì điều này sẽ dẫn đến một lỗi logic.
Ví dụ, hãy xem điều gì xảy ra khi chúng ta vô tình thụt đầu dòng dòng cảm ơn các ảo thuật gia như một nhóm vì đã trình diễn một buổi biểu diễn tuyệt vời:
magicians = ['alice', 'david', 'carolina']
for magician in magicians:
print(f"{magician.title()}, that was a great trick!")
print(f"I can't wait to see your next trick, {magician.title()}.\n")
print("Thank you everyone, that was a great magic show!")
Vì dòng cuối cùng được thụt đầu dòng, nó được in một lần cho mỗi người trong danh sách:
Alice, that was a great trick!
I can't wait to see your next trick, Alice.
Thank you everyone, that was a great magic show!
David, that was a great trick!
I can't wait to see your next trick, David.
Thank you everyone, that was a great magic show!
Carolina, that was a great trick!
I can't wait to see your next trick, Carolina.
Thank you everyone, that was a great magic show!
Đây là một lỗi logic khác, tương tự như lỗi trong "Quên thụt đầu dòng các dòng bổ sung". Vì Python không biết bạn đang cố gắng làm gì với mã của mình, nó sẽ chạy tất cả mã được viết bằng cú pháp hợp lệ. Nếu một hành động được lặp lại nhiều lần khi nó chỉ nên được thực thi một lần, bạn có thể cần phải bỏ thụt đầu dòng mã cho hành động đó.
Quên dấu hai chấm
Dấu hai chấm ở cuối câu lệnh for cho Python biết diễn giải dòng tiếp theo là bắt đầu của một vòng lặp.
magicians = ['alice', 'david', 'carolina']
for magician in magicians
print(magician)
Nếu bạn vô tình quên dấu hai chấm, bạn sẽ nhận được lỗi cú pháp vì Python không biết chính xác bạn đang cố gắng làm gì:
File "magicians.py", line 2
for magician in magicians
^
SyntaxError: expected ':'
Python không biết liệu bạn chỉ đơn giản quên dấu hai chấm, hay bạn định viết thêm mã để thiết lập một vòng lặp phức tạp hơn. Nếu trình thông dịch có thể xác định một cách khắc phục có thể, nó sẽ đề xuất một, như thêm dấu hai chấm ở cuối dòng, như nó làm ở đây với phản hồi expected ':'. Một số lỗi có cách khắc phục dễ dàng, rõ ràng, nhờ vào các đề xuất trong traceback của Python. Một số lỗi khó khắc phục hơn nhiều, ngay cả khi cách khắc phục cuối cùng chỉ liên quan đến một ký tự duy nhất. Đừng cảm thấy tồi tệ khi một cách khắc phục nhỏ mất nhiều thời gian để tìm ra; bạn hoàn toàn không cô đơn trong trải nghiệm này.
Comments