Đối số chính của cuốn sách là phiên bản ngoại lệ của mã tốt hơn bởi vì nó sẽ nắm bắt mọi thứ mà bạn có thể đã bỏ qua nếu bạn cố gắng viết kiểm tra lỗi của riêng bạn.
Tôi nghĩ rằng tuyên bố này chỉ đúng trong những trường hợp rất cụ thể - nơi bạn không quan tâm nếu đầu ra là chính xác.
Không có nghi ngờ rằng việc nâng cao ngoại lệ là một thực hành đúng đắn và an toàn. Bạn nên làm như vậy bất cứ khi nào bạn cảm thấy có điều gì đó trong trạng thái hiện tại của chương trình mà bạn (với tư cách là nhà phát triển) không thể hoặc không muốn giải quyết.
Ví dụ của bạn, tuy nhiên, là về việc bắt ngoại lệ. Nếu bạn bắt gặp một ngoại lệ, bạn không tự bảo vệ mình khỏi các tình huống mà bạn có thể đã bỏ qua. Bạn đang làm chính xác điều ngược lại: bạn cho rằng bạn đã bỏ qua bất kỳ kịch bản nào có thể gây ra loại ngoại lệ này, và do đó bạn tự tin rằng việc nắm bắt nó (và do đó ngăn không cho chương trình thoát ra, như bất kỳ ngoại lệ chưa được khai thác nào).
Sử dụng phương pháp ngoại lệ, nếu bạn thấy ValueError
ngoại lệ, bạn bỏ qua một dòng. Sử dụng phương pháp tiếp cận không ngoại lệ truyền thống, bạn đếm số lượng giá trị được trả về split
và nếu nó nhỏ hơn 2, bạn bỏ qua một dòng. Bạn có nên cảm thấy an toàn hơn với cách tiếp cận ngoại lệ, vì bạn có thể đã quên một số tình huống "lỗi" khác trong kiểm tra lỗi truyền thống của mình và except ValueError
sẽ bắt chúng cho bạn?
Điều này phụ thuộc vào bản chất của chương trình của bạn.
Nếu bạn đang viết, ví dụ, trình duyệt web hoặc trình phát video, một vấn đề với đầu vào sẽ không khiến nó bị sập với một ngoại lệ chưa được lưu. Tốt hơn hết là xuất ra thứ gì đó hợp lý từ xa (ngay cả khi, nói đúng ra là không chính xác) hơn là bỏ.
Nếu bạn đang viết một ứng dụng mà vấn đề chính xác (như phần mềm kinh doanh hoặc kỹ thuật), đây sẽ là một cách tiếp cận tồi tệ. Nếu bạn quên một số kịch bản phát sinh ValueError
, điều tồi tệ nhất bạn có thể làm là âm thầm bỏ qua kịch bản chưa biết này và chỉ cần bỏ qua dòng. Đó là cách các lỗi rất tinh vi và tốn kém kết thúc trong phần mềm.
Bạn có thể nghĩ rằng cách duy nhất bạn có thể thấy ValueError
trong mã này là nếu split
chỉ được trả về một giá trị (thay vì hai). Nhưng điều gì sẽ xảy ra nếu print
câu lệnh của bạn sau đó bắt đầu sử dụng một biểu thức tăng lên ValueError
trong một số điều kiện? Điều này sẽ khiến bạn bỏ qua một số dòng không phải vì họ bỏ lỡ :
, mà vì print
thất bại trên chúng. Đây là một ví dụ về một lỗi tinh vi mà tôi đã đề cập trước đó - bạn sẽ không nhận thấy bất cứ điều gì, chỉ mất một số dòng.
Đề nghị của tôi là tránh bắt (nhưng không nêu ra!) Ngoại lệ trong mã nơi sản xuất đầu ra không chính xác còn tệ hơn thoát. Lần duy nhất tôi bắt gặp một ngoại lệ trong mã như vậy là khi tôi có một biểu thức thực sự tầm thường, vì vậy tôi có thể dễ dàng suy luận điều gì có thể gây ra từng loại ngoại lệ có thể.
Đối với tác động hiệu suất của việc sử dụng các ngoại lệ, nó là tầm thường (trong Python) trừ khi gặp phải các ngoại lệ thường xuyên.
Nếu bạn sử dụng ngoại lệ để xử lý các điều kiện xảy ra thường xuyên, trong một số trường hợp, bạn có thể phải trả một chi phí hiệu suất rất lớn. Ví dụ, giả sử bạn thực hiện từ xa một số lệnh. Bạn có thể kiểm tra xem văn bản lệnh của bạn vượt qua ít nhất là xác thực tối thiểu (ví dụ: cú pháp). Hoặc bạn có thể đợi một ngoại lệ được đưa ra (điều này chỉ xảy ra sau khi máy chủ từ xa phân tích cú pháp lệnh của bạn và tìm thấy sự cố với nó). Rõ ràng, trước đây là đơn đặt hàng cường độ nhanh hơn. Một ví dụ đơn giản khác: bạn có thể kiểm tra xem một số có nhanh hơn 0 ~ 10 lần so với cố gắng thực hiện phép chia hay không và sau đó bắt ngoại lệ ZeroDivisionError.
Những cân nhắc này chỉ quan trọng nếu bạn thường xuyên gửi các chuỗi lệnh không đúng định dạng đến các máy chủ từ xa hoặc nhận các đối số có giá trị bằng 0 mà bạn sử dụng để phân chia.
Lưu ý: Tôi giả sử bạn sẽ sử dụng except ValueError
thay vì chỉ except
; như những người khác đã chỉ ra, và như cuốn sách đã nói trong một vài trang, bạn không bao giờ nên sử dụng trần except
.
Một lưu ý khác: cách tiếp cận không ngoại lệ thích hợp là đếm số lượng giá trị được trả về split
, thay vì tìm kiếm :
. Cái sau thì quá chậm, vì nó lặp lại công việc được thực hiện bởi split
và có thể tăng gần gấp đôi thời gian thực hiện.