2009-04-16 40 views

Trả lời

25

Nó được coi là thực hành tốt để không thường bắt gốc đối tượng ngoại lệ, nhưng thay vào đó để bắt những người cụ thể hơn - ví dụ IOException.

Hãy xem xét nếu xảy ra ngoại lệ bộ nhớ - chỉ cần sử dụng "pass" sẽ không rời khỏi chương trình của bạn ở trạng thái tốt.

Khá nhiều lần duy nhất bạn nên bắt Ngoại lệ ở cấp cao nhất của chương trình, nơi bạn có thể (cố gắng) ghi nhật ký, hiển thị lỗi và thoát ra một cách duyên dáng nhất có thể.

+2

thói quen xấu này cũng sẽ tạo ra những cơn ác mộng đáng kể.Đặc biệt là khi các trường hợp ngoại lệ khác so với những trường hợp bạn nghĩ đến được nêu trong thử/ngoại trừ. Và điều này chỉ đơn giản xảy ra ... – vaab

3

bởi vì nó cho rằng bạn đang bắt quá nhiều. và nó đúng.

1

Ngoại lệ được nêu ra khi có điều gì đó ... ngoại lệ xảy ra. Nó thường là một điều tốt mà chương trình chấm dứt.

Bạn có thể bỏ qua một số ngoại lệ, nhưng IMO không có lý do chính đáng để bắt một lớp cơ sở như vậy.

+4

Hey. Tôi không nghĩ rằng tôi đồng ý rằng 'không có lý do chính đáng' - tôi có thể tưởng tượng, ví dụ, một chương trình GUI làm tăng ngoại lệ khi thử một hoạt động cụ thể trên một tập dữ liệu đặc biệt phức tạp. Đó là tất cả tốt và tốt như một lập trình viên để nói rằng một ngoại lệ không mong muốn sẽ kết thúc chương trình với một dấu vết ngăn xếp (thất bại sớm), nhưng trong thực tế những gì người dùng muốn là cho các hoạt động hiện tại để không gracefully, có thể với một hộp thư hoặc logfile và sau đó để GUI tiếp tục hoạt động để chúng có thể lưu dữ liệu của họ trước khi bất cứ điều gì khác xấu xảy ra. –

+1

Tôi hoàn toàn đồng ý, tôi đã đề cập đến cách OP bỏ qua các ngoại lệ với 'pass'. Tôi nên làm cho quan điểm của tôi rõ ràng hơn. –

+0

Hãy bắt đầu sự tha thứ của bạn, đủ công bằng rồi. –

-1

Bắt ngoại lệ (không tăng lại) có 2 tác dụng phụ thực sự xấu: lỗi bị ăn, vì vậy bạn mất dấu vết ngăn xếp, nhưng cũng ctrl-c (hoặc bất kỳ khóa ngắt nào trên hệ điều hành của bạn) xử lý ở đây.

Hành vi điển hình của các chương trình như thế này là không thể dừng hoặc ctrl-c làm luồng điều khiển bỏ qua (tới trình xử lý ngoại lệ), rồi tiếp tục. Sau đó, một trong hai mã không thể bị gián đoạn, hoặc bạn cần phải bấm vào ctrl-c để làm cho nó dừng lại.

+2

Điều này không còn đúng với Python 2.6, KeyboardInterrupt không còn được thừa hưởng từ Ngoại lệ. –

+0

Bạn không bị mất dấu vết ngăn xếp. Chỉ cần sử dụng mô-đun 'traceback' w/sys.exc_info(). – PeqNP

15

Thực tiễn tốt là chỉ bắt được một số loại rất hẹp. 'Ngoại lệ' quá chung chung - bạn sẽ không chỉ bắt lỗi mà bạn đã lên kế hoạch, mà còn các lỗi khác nữa, có thể che giấu lỗi trong mã của bạn để chẩn đoán nhanh hơn nếu chúng không bị bắt hoặc có thể được xử lý tốt hơn bởi một trình xử lý ngoại lệ mức rất cao. Có nói rằng, kể từ Python2.6, việc bắt ngoại lệ đã trở nên hợp lý hơn rất nhiều, bởi vì tất cả các ngoại lệ mà bạn không muốn bắt (SystemExit, KeyboardInterrupt) không còn được thừa hưởng từ Ngoại lệ nữa. Thay vào đó, họ thừa kế từ một BaseException chung. Điều này đã được thực hiện cố tình để làm cho việc đánh bắt ngoại lệ tương đối vô hại, vì nó là một thành ngữ phổ biến.

Xem PEP 3110 để biết chi tiết & các gói trong tương lai.

0

như câu trả lời của Greg, 'Ngoại lệ' là lớp cơ sở và ngoại lệ nên được bắt nguồn từ lớp này, xem thêm exceptions.Exception.

Dưới đây là một danh sách rất hữu ích của lỗi trong pydocs

Cũng lưu ý các module traceback rất tiện dụng cho phép bạn tìm ra nơi các ngoại lệ xảy ra. Chỉ sử dụng 'ngoại trừ: ...' sẽ cho bạn thấy Lỗi nào bạn nên sử dụng tốt nhất trong trường hợp của mình. Ví dụ: hãy thử mã này (chuyển đổi nhận xét), có lẽ bạn sẽ chấp nhận nó:

import traceback 
#absent = 'nothing' 
try: 
    something = absent 
except NameError: 
    traceback.print_exc() 
else: 
    print("you get here only when you uncomment 'absent'") 
Các vấn đề liên quan