Bạn thường nghe rằng Python khuyến khích phong cách EAFP ("dễ xin tha thứ hơn là cho phép") so với kiểu LBYL ("nhìn trước khi bạn nhảy"). Đối với tôi, đó là vấn đề hiệu quả và dễ đọc.
Trong ví dụ của bạn (giả sử thay vì trả về danh sách hoặc chuỗi rỗng, hàm sẽ trả về danh sách hoặc None
), nếu bạn cho rằng 99% thời gian result
sẽ thực sự chứa thứ gì đó có thể lặp lại, tôi sẽ sử dụng try/except
phương pháp này. Nó sẽ nhanh hơn nếu các ngoại lệ thực sự là đặc biệt. Nếu result
là None
hơn 50% thời gian, thì sử dụng if
có lẽ tốt hơn.
Để hỗ trợ điều này với một vài phép đo:
>>> import timeit
>>> timeit.timeit(setup="a=1;b=1", stmt="a/b") # no error checking
0.06379691968322732
>>> timeit.timeit(setup="a=1;b=1", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.0829463709378615
>>> timeit.timeit(setup="a=1;b=0", stmt="try:\n a/b\nexcept ZeroDivisionError:\n pass")
0.5070195056614466
>>> timeit.timeit(setup="a=1;b=1", stmt="if b!=0:\n a/b")
0.11940114974277094
>>> timeit.timeit(setup="a=1;b=0", stmt="if b!=0:\n a/b")
0.051202772912802175
Vì vậy, trong khi một if
tuyên bố luôn khiến bạn phải trả giá, thì việc thiết lập một try/except
khối gần như miễn phí . Nhưng khi một Exception
thực tế xảy ra, chi phí cao hơn nhiều.
Đạo đức:
- Hoàn toàn ổn (và "pythonic") để sử dụng
try/except
cho kiểm soát dòng chảy,
- nhưng nó có ý nghĩa nhất khi
Exception
s thực sự đặc biệt.
Từ các tài liệu Python:
EAFP
Dễ dàng yêu cầu sự tha thứ hơn sự cho phép. Kiểu mã hóa Python phổ biến này giả định sự tồn tại của các khóa hoặc thuộc tính hợp lệ và bắt ngoại lệ nếu giả định chứng minh là sai. Phong cách sạch sẽ và nhanh chóng này được đặc trưng bởi sự hiện diện của nhiều
try
và except
tuyên bố. Kỹ thuật này tương phản với
phong cách LBYL phổ biến đối với nhiều ngôn ngữ khác như C.