Ngoại trừ có cần thiết trong Python không?

Việc sử dụng khối the

results = [1/num for num in nums]
1 để xử lý các ngoại lệ trong Python là rất phổ biến. Nó cho phép chúng tôi áp dụng một số thao tác đặc biệt khi có sự cố xảy ra

Tuy nhiên, có một trường hợp đặc biệt là

  • Chúng tôi biết rằng ngoại lệ này có thể xảy ra
  • Chúng tôi không quan tâm đến ngoại lệ này
  • Nếu nó xảy ra, chỉ cần bỏ qua nó mà không làm gì cả

Nếu tình huống thỏa mãn các điều kiện trên, bạn không phải sử dụng

results = [1/num for num in nums]
1 để xử lý các trường hợp ngoại lệ. Thay vào đó, thư viện tích hợp Python
results = [1/num for num in nums]
3 cung cấp một hàm có tên là
results = [1/num for num in nums]
4 để xử lý việc này một cách tinh tế hơn

Xác định các vấn đề

Ảnh của Romain Vignes trên Bapt

Giả sử chúng ta có một danh sách các số có thể chứa các số 0 trong đó. Chúng tôi muốn lấy số nghịch đảo của mọi số trong danh sách này và sau đó có tổng của chúng. Nếu có số không, chỉ cần bỏ qua chúng

Đầu tiên, hãy sử dụng thư viện ngẫu nhiên để tạo một danh sách như vậy

import randomnums = [random.randint[-3, 3] for i in range[20]]

Đoạn mã trên tạo ra một danh sách các số nguyên giữa [-3, 3] với kích thước 20. Xin lưu ý rằng bạn có thể có một danh sách không có bất kỳ số không nào. Nếu điều này xảy ra, chỉ cần tạo một cái khác. Chúng tôi sẽ cần một số số không trong thí nghiệm này

Bây giờ, giả sử chúng ta muốn lấy số nghịch đảo của tất cả các số trong danh sách này. Lưu ý rằng số 0 không có nghịch đảo. Vì vậy, nếu chúng ta viết mã như sau mà không xử lý ngoại lệ, thì một

results = [1/num for num in nums]
5 sẽ bị ném ra

results = [1/num for num in nums]

Sử dụng Thử ngoại trừ

Ảnh của Wil Stewart trên Bapt

Cách phổ biến và trực quan nhất để giải quyết vấn đề này là có một khối

results = [1/num for num in nums]
1 để bắt ngoại lệ
results = [1/num for num in nums]
5 và bỏ qua nó

result = 0for num in nums:
try:
result += 1/num
except ZeroDivisionError:
pass
result

Trong đoạn mã trên, chúng tôi bắt gặp ngoại lệ

results = [1/num for num in nums]
5 và sử dụng
results = [1/num for num in nums]
9 để bỏ qua nó. Vì vậy, khi ngoại lệ này xảy ra, sẽ không có gì bị ném ra và chương trình sẽ tiếp tục chạy bằng cách bỏ qua số 0

Sử dụng chức năng Suppress

Ảnh của Federico Bottos trên Bapt

Bây giờ, tôi sẽ giới thiệu cho bạn một cách tiếp cận khác, giúp mã của bạn thanh lịch hơn

Trước khi sử dụng phương pháp này, trước tiên chúng ta cần nhập nó từ

results = [1/num for num in nums]
3

from contextlib import suppress

Cần sử dụng hàm

results = [1/num for num in nums]
4 với câu lệnh
result = 0for num in nums:
try:
result += 1/num
except ZeroDivisionError:
pass
result
2 như sau

result = 0for num in nums:
with suppress[ZeroDivisionError]:
result += 1/num
result

Điều đó không phải ngắn gọn và trực quan hơn sao?

Vì vậy, với hàm

results = [1/num for num in nums]
4, ngoại lệ được truyền vào dưới dạng tham số sẽ bị bỏ qua

Tại sao chúng ta phải sử dụng “Suppress”?

Phần này được cập nhật dựa trên câu hỏi từ phản hồi của @Felix

Câu trả lời ngắn gọn là. Không, bạn không cần phải sử dụng nó

Trong câu hỏi mình được hỏi tại sao không sửa như sau

result = sum[[1/x for x in nums if x != 0]]

Điều đó hoàn toàn đúng. Trong bài viết này, tôi chỉ muốn tạo ra một kịch bản như vậy để tôi có thể chứng minh việc triệt tiêu. Ví dụ của tôi không hoàn hảo, vì thực sự tốt hơn là nên sửa bằng giải pháp trên hơn là sử dụng chức năng triệt tiêu. Nhưng tôi nghĩ giá trị của hàm triệt tiêu tồn tại trong các tình huống khác. Ví dụ, nếu danh sách như thế này thì sao

nums = [3, -1, -2, 1, 1, 0, 3, 1, -2, 1, 0, -1, -1, -1, 3, -2, -1, 3, '3', -1] 

Xin lưu ý rằng có một chuỗi '3' ở vị trí cuối cùng thứ hai. Bây giờ, chúng tôi có hai trường hợp ngoại lệ có thể. Bạn cũng có thể xử lý theo cách trên

result = sum[[1/x for x in nums if x != 0 and type[x] == int]] 

Hoặc, với chức năng triệt tiêu, bạn chỉ cần thêm một loại ngoại lệ khác

for num in nums:
with suppress[ZeroDivisionError, TypeError]:
result += 1/num

Sau đó, nếu có nhiều ngoại lệ có thể xảy ra thì sao?

Ngoài ra, nếu bạn có nhiều hơn 2 trường hợp ngoại lệ thì sao?

for num in nums:
with suppress[Exception]:
result += 1/num

Vì vậy, bạn đã chặn mọi loại ngoại lệ. ]

giới hạn

Ảnh của Markus Spiske trên Bapt

Tuy nhiên, có một giới hạn của chức năng

results = [1/num for num in nums]
4. Nghĩa là, bạn không thể đặt vòng lặp for của mình bên trong câu lệnh
results = [1/num for num in nums]
4
result = 0for num in nums:
try:
result += 1/num
except ZeroDivisionError:
pass
result
2 như sau

results = [1/num for num in nums]
0

Tại sao chúng ta có một kết quả khác nhau ở đây? . Mặc dù ngoại lệ vẫn bị bỏ qua nhưng tất cả các số sau số 0 cũng sẽ bị bỏ qua

suy nghĩ

Ảnh của Thought Catalog trên Bapt

Trong bài viết này, tôi đã chia sẻ một cách tiếp cận khác đối với hàm

results = [1/num for num in nums]
1 khi bạn chỉ muốn bắt ngoại lệ và bỏ qua nó, đó là hàm
results = [1/num for num in nums]
4 từ
results = [1/num for num in nums]
3, một thư viện tích hợp sẵn trong Python. Tôi tin rằng nó thanh lịch hơn về phong cách viết mã

Tuy nhiên, tôi cũng muốn đưa ra một số suy nghĩ của tôi về điều này

  • Nó có một hạn chế là chúng ta không thể đặt phép lặp chẳng hạn như vòng lặp for vào trong đó
  • Chúng tôi sẽ cần nhập chức năng trước khi sử dụng, vì vậy có thể sử dụng chức năng này khi chúng tôi muốn sử dụng nó ở nhiều vị trí trong mã của mình

Mỗi ngày chúng ta có thể học được điều gì đó. Mã hóa vui vẻ

Tham gia Medium với liên kết giới thiệu của tôi — Christopher Tao

Là thành viên Phương tiện, một phần phí thành viên của bạn sẽ được chuyển đến các tác giả mà bạn đã đọc và bạn có toàn quyền truy cập vào mọi câu chuyện…

trung bình. com

Nếu bạn cảm thấy bài viết của tôi hữu ích, hãy cân nhắc tham gia Medium Membership để ủng hộ tôi và hàng ngàn người viết khác. [Nhấp vào liên kết ở trên]

Có thể có một lần thử mà không có ngoại lệ?

Có, có thể có khối thử mà không có khối bắt bằng cách sử dụng khối cuối cùng . Như chúng ta đã biết, một khối cuối cùng sẽ luôn thực thi ngay cả khi có một ngoại lệ xảy ra trong một khối thử, ngoại trừ Hệ thống. exit[] nó sẽ thực thi luôn.

Tôi có thể viết khối thử mà không có ngoại trừ trong Python không?

Khối thử cho phép bạn kiểm tra lỗi của một khối mã. Khối except cho phép bạn xử lý lỗi . Khối khác cho phép bạn thực thi mã khi không có lỗi. Khối cuối cùng cho phép bạn thực thi mã, bất kể kết quả của khối thử và ngoại trừ.

Chúng tôi có thể sử dụng cuối cùng mà không ngoại trừ trong Python không?

Người ta có thể sử dụng finally ngay sau lần thử mà không cần sử dụng khối ngoại trừ , nhưng không có ngoại lệ nào được xử lý trong trường hợp đó.

Tôi có thể sử dụng cái gì thay vì thử và ngoại trừ trong Python?

Nếu tình huống thỏa mãn các điều kiện trên, bạn không cần phải sử dụng thử. ngoại trừ. để xử lý các ngoại lệ. Thay vào đó, thư viện contextlib tích hợp sẵn của Python cung cấp một hàm gọi là suppress để xử lý việc này một cách tinh tế hơn.

Chủ Đề