Python: Làm thế nào để bỏ qua một ngoại lệ và tiến hành?


239

Tôi có một thử ... ngoại trừ khối trong mã của tôi và Khi một ngoại lệ là ném. Tôi thực sự chỉ muốn tiếp tục với mã vì trong trường hợp đó, mọi thứ vẫn có thể chạy tốt. Vấn đề là nếu bạn rời khỏi ngoại trừ: khối trống hoặc không có gì, nó sẽ cho bạn một lỗi cú pháp. Tôi không thể sử dụng tiếp tục vì nó không trong vòng lặp. Có một từ khóa tôi có thể sử dụng mà nói với mã để chỉ tiếp tục đi?

359
except: 
    pass 
+64

ngoại trừ Ngoại lệ: vượt qua # quan trọng không được nuốt các ngoại lệ khác! 22 feb. 092009-02-22 16:46:45

+8

@Aaron - Tôi đồng ý, nhưng câu hỏi không phải là nếu đây là ý tưởng tốt/xấu 23 feb. 092009-02-23 20:05:24

+15

Điều này sẽ bắt SystemExit, KeyboardInterrupt và những thứ khác mà bạn có thể không muốn bắt. 02 jan. 102010-01-02 01:13:31

+1

Nó sẽ không bắt KeyboardInterrupt. Ví dụ: 'khi Đúng: ' ' thử: 'f = open ('filedoesnotexist.txt')' ' trừ: ' 'pass' KeyboardInterrupt dừng và thoát khỏi các mã. 24 jul. 122012-07-24 15:59:51

+14

@ChthonicProject một 'ngoại trừ' sẽ bắt bất kỳ ngoại lệ, bao gồm một KeyboardInterrupt, nhưng chỉ khi nó xảy ra bên trong 'try'. Trong ví dụ của bạn ở đó, một KeyboardInterrupt có thể xảy ra trước khi 'try' hoặc bên trong' except', nơi nó sẽ không bị bắt. Nếu bạn chạy một ví dụ như 'while True:' 'try: pass'' except: pass', bạn sẽ thấy rằng KeyboardInterrupt bị bắt chỉ khoảng 50% thời gian. Nếu bạn 'time.sleep (1)' bên trong 'try', bạn sẽ thấy rằng nó bị bắt gần như mọi lúc. 22 mar. 132013-03-22 08:39:50


12

Hãy thử điều này:

try: 
    blah() 
except: 
    pass 

202

Tiêu chuẩn "nop" bằng Python là pass tuyên bố:

try: 
    do_something() 
except Exception: 
    pass 

Vì ném ngoại lệ cuối cùng được nhớ đến bằng Python, một số các các đối tượng liên quan đến câu lệnh ném ngoại lệ được lưu giữ trực tiếp vô thời hạn (thực tế, cho đến khi ngoại lệ tiếp theo). Trong trường hợp này là quan trọng đối với bạn và (thường), bạn không cần phải nhớ những ngoại lệ ném cuối cùng, bạn có thể muốn làm như sau thay vì pass:

try: 
    do_something() 
except Exception: 
    sys.exc_clear() 

này xóa ném ngoại lệ cuối cùng.

+26

Đây là câu trả lời tốt hơn câu trả lời được chấp nhận bởi vì nó sử dụng "ngoại trừ ngoại lệ:" thay vì chỉ "ngoại trừ:" như những người khác đã chỉ ra sẽ nuốt nhầm những thứ khác mà bạn không muốn bắt như SystemExit và KeyboardInterrupt . 11 jul. 112011-07-11 21:50:28

+4

+1 Nó cũng xóa các lỗi đó là quan trọng khi chạy unittests và mong đợi ngoại lệ 26 oct. 112011-10-26 13:50:55

  0

Lưu ý rằng 'exc_clear' đã được gỡ bỏ trong python 3. https: // docs.python.org/3/whatsnew/3.0.html#index-22. Đối với một số cách để giải quyết điều này trong Python 3 xem tại đây: https://cosmicpercolator.com/2016/01/13/exception-leaks-in-python-2-and-3/ 06 mar. 182018-03-06 18:59:18


114

Có một cách mới để làm được điều này sắp tới trong Python 3.4:

from contextlib import suppress 

with suppress(Exception): 
    # your code 

Đây là cam kết rằng thêm nó: http://hg.python.org/cpython/rev/406b47c64480

Và đây là tác giả, Raymond hettinger, nói chuyện về vấn đề này và tất cả các loại độ nóng Python khác (bit có liên quan tại 43:30): http://www.youtube.com/watch?v=OSGv2VnC0go

Nếu bạn muốn mô phỏng từ khóa except trống và cũng bỏ qua những thứ như KeyboardInterrupt - mặc dù bạn thường không - bạn có thể sử dụng with suppress(BaseException).

Chỉnh sửa: Có vẻ như ignored đã được đổi tên thành suppress trước bản phát hành 3.4.

+1

Tôi không chắc chắn tôi thích giải pháp này ... Tôi đoán ý tưởng là chúng tôi đã thay thế 3 dòng chỉ với 1 (thử, ngoại trừ và vượt qua tất cả được hợp nhất thành một.) Điều chính tôi phản đối là cách điều này giới thiệu một từ khóa mới có vẻ minh mẫn điều gì đó bạn có lẽ không nên làm ... có vẻ như bạn nên luôn luôn có ít nhất đăng nhập ngoại lệ bạn đang bắt ... 14 oct. 132013-10-14 13:13:09

  0

Khi một ngoại lệ được nâng lên, nó sẽ tiếp tục mã sau khi try/catch hoặc bất cứ thứ gì nằm ngoài ' with' block? 13 nov. 132013-11-13 07:45:05

+1

Điều này tương đương với việc gói mã của bạn trong một 'try ... catch: pass', vì vậy nếu một ngoại lệ được nâng lên bên trong khối, việc thực hiện sẽ tiếp tục sau khi kết thúc khối. 14 nov. 132013-11-14 08:45:10

+4

@ JackO'Connor Vâng, điều đó làm cho nó khá vô dụng ... Tôi nghĩ nó sẽ bỏ qua những ngoại lệ như đã hứa. 04 dec. 132013-12-04 20:21:50

+2

@ArtOfWarfare Điều gì sẽ xảy ra nếu tôi nói, tôi sẽ cung cấp cho bạn một số nguyên, nhưng đôi khi tôi sẽ đưa nó cho bạn trong một bộ dữ liệu đơn, và tôi sẽ không nói cho bạn biết khi nào tôi làm việc này hay cái kia; bây giờ công việc của bạn là luôn luôn cho tôi trở lại số nguyên? Có lẽ bạn sẽ đánh giá cao việc có thể viết một cái gì đó như 'với suppress (TypeError): return data [0]' (ví dụ dài hơn: http://pastebin.com/gcvAGqEP) 02 may. 142014-05-02 21:03:25

  0

@Navin Python không thể giả vờ rằng một ngoại lệ đã không không tồn tại. Giả sử tôi có một câu lệnh như 'y = f (x) * g (x)', và sau đó 'f (x)' đặt ra một ngoại lệ. Ngay cả khi Python bỏ qua nó, 'f (x)' không bao giờ trả về một giá trị, vì vậy không có cách nào để Python gán giá trị cho 'y'. Các nhà thiết kế có thể đã nói "giả định một giá trị của Không" hoặc "bỏ qua các câu lệnh có chứa bất kỳ biểu thức nào không đánh giá được," nhưng điều đó sẽ kết thúc rất khó hiểu. Sử dụng các khối 'try' để nhóm các câu lệnh thất bại với nhau sẽ giữ cho mọi thứ đơn giản. 14 jan. 152015-01-14 17:14:23

  0

@ JackO'Connor Đủ công bằng. Tôi đã hy vọng sẽ có một cách để thay thế một biểu thức với Không nếu nó làm tăng một ngoại lệ. 14 jan. 152015-01-14 18:07:12

  0

Nó có thể được thực hiện nội tuyến? Ví dụ một cái gì đó như 'supress (myFunc, suppressedException, returnValueOnFailure)'? 23 jun. 152015-06-23 01:43:01

  0

@ JeromeJ bạn không thể làm điều đó với 'suppress' trực tiếp, bởi vì nó là một người quản lý ngữ cảnh. (Để biết chi tiết về cách các trình quản lý ngữ cảnh hoạt động, hãy xem tại đây: https://docs.python.org/3.4/library/stdtypes.html#typecontextmanager) Nhưng sẽ rất đơn giản để xác định hàm 'callCatchingExceptions' của riêng bạn đã sử dụng' suppress 'hoặc một khối' try' bình thường ở bên trong, nếu bạn muốn. 24 jun. 152015-06-24 14:01:27

+1

FYI, django hoàn nguyên việc sử dụng 'bằng cách loại bỏ (Ngoại lệ)' vào năm 2017-09, vì thử/ngoại trừ hoạt động tốt hơn. Kiểm tra cam kết này [Đã hoàn nguyên "Cố định # 27818 - Thay thế thử/except/pass bằng contextlib.su…] (https://github.com/django/django/commit/6e4c6281dbb7ee12bcdc22620894edb4e9cf623f) 07 nov. 172017-11-07 07:00:17