Câu hỏi Bắt nhiều ngoại lệ trong một dòng (trừ khối)


Tôi biết rằng tôi có thể làm:

try:
    # do something that may fail
except:
    # do this if ANYTHING goes wrong

Tôi cũng có thể làm điều này:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreTooShortException:
    # stand on a ladder

Nhưng nếu tôi muốn làm điều tương tự bên trong hai trường hợp ngoại lệ khác nhau, điều tốt nhất tôi có thể nghĩ ngay bây giờ là làm điều này:

try:
    # do something that may fail
except IDontLikeYouException:
    # say please
except YouAreBeingMeanException:
    # say please

Có cách nào để tôi có thể làm một cái gì đó như thế này không (vì hành động đưa vào cả hai trường hợp ngoại lệ là say please):

try:
    # do something that may fail
except IDontLikeYouException, YouAreBeingMeanException:
    # say please

Bây giờ điều này thực sự sẽ không hoạt động, vì nó khớp với cú pháp cho:

try:
    # do something that may fail
except Exception, e:
    # say please

Vì vậy, nỗ lực của tôi để nắm bắt hai ngoại lệ riêng biệt không chính xác đi qua.

Có cách nào để làm việc này không?


1963
2018-06-24 15:55


gốc




Các câu trả lời:


Từ Tài liệu Python:

Một mệnh đề ngoại trừ có thể đặt tên cho nhiều ngoại lệ như một bộ dữ liệu được tạo dấu ngoặc đơn, ví dụ

except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Hoặc, đối với Python 2 chỉ:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    pass

Việc tách biệt ngoại lệ khỏi biến bằng dấu phẩy sẽ vẫn hoạt động trong Python 2.6 và 2.7, nhưng hiện không còn được dùng nữa và không hoạt động trong Python 3; bây giờ bạn nên sử dụng as.


2712
2018-06-24 15:56



Có thể lưu trữ các ngoại lệ mong muốn trong một iterable, và sau đó bắt các iterable? Tôi đang cố biến danh sách cảnh báo thành lỗi bằng warnings.filterwarningsvà tôi không muốn phải chỉ định danh sách cảnh báo hai lần. - BallpointBen
Tôi đã thử nó ... với một listvà kết quả là TypeError. Có vẻ như các lỗi phải nằm trong tuple để bắt được làm việc như mong đợi. - BallpointBen
Tại sao bạn đã từng sử dụng một danh sách khi bạn thấy rõ ràng rằng nó được ghi lại rằng một bộ tuple là cần thiết trong trường hợp này? - bernie
Vẫn chưa rõ liệu "tuple được viết hoa" chỉ đơn thuần là cú pháp hay cần phải có một tattle bona fide. "Dấu ngoặc đơn" là gây hiểu lầm bởi vì bạn có thể tạo một bộ dữ liệu không có dấu ngoặc đơn ở nơi khác và sau đó sử dụng nó trong excepthàng. Nó chỉ cần thiết được ngoặc đơn nếu được tạo trong except hàng. - BallpointBen


Làm thế nào để tôi bắt được nhiều ngoại lệ trong một dòng (ngoại trừ khối)

Làm cái này:

try:
    may_raise_specific_errors():
except (SpecificErrorOne, SpecificErrorTwo) as error:
    handle(error) # might log or have some other default behavior...

Các dấu ngoặc đơn được yêu cầu do cú pháp cũ hơn sử dụng dấu phẩy để gán đối tượng lỗi cho một tên. Các as từ khóa được sử dụng cho nhiệm vụ. Bạn có thể sử dụng bất kỳ tên nào cho đối tượng lỗi, tôi thích error cá nhân.

Thực hành tốt nhất

Để thực hiện điều này theo cách hiện tại và tương thích với Python, bạn cần tách biệt các ngoại lệ bằng dấu phẩy và bọc chúng bằng dấu ngoặc đơn để phân biệt cú pháp trước đó đã gán cá thể ngoại lệ cho tên biến bằng cách làm theo kiểu Ngoại lệ để bắt gặp dấu phẩy.

Dưới đây là ví dụ về cách sử dụng đơn giản:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError): # the parens are necessary
    quit(0)

Tôi chỉ xác định những trường hợp ngoại lệ này để tránh các lỗi ẩn, nếu tôi gặp phải, tôi mong đợi dấu vết ngăn xếp đầy đủ từ đó.

Đây là tài liệu ở đây: https://docs.python.org/tutorial/errors.html

Bạn có thể gán ngoại lệ cho biến, (e là phổ biến, nhưng bạn có thể thích một biến tiết hơn nếu bạn có xử lý ngoại lệ dài hoặc IDE của bạn chỉ làm nổi bật các lựa chọn lớn hơn, như của tôi.) Cá thể có thuộc tính args. Đây là một ví dụ:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError) as err: 
    print(err)
    print(err.args)
    quit(0)

Lưu ý rằng trong Python 3, err đối tượng nằm ngoài phạm vi khi except khối được kết luận.

Không được chấp nhận

Bạn có thể thấy mã chỉ định lỗi bằng dấu phẩy. Việc sử dụng này, biểu mẫu duy nhất có sẵn trong Python 2.5 trở về trước, không được chấp nhận và nếu bạn muốn mã của bạn được tương thích về phía trước trong Python 3, bạn nên cập nhật cú pháp để sử dụng biểu mẫu mới:

try:
    mainstuff()
except (KeyboardInterrupt, EOFError), err: # don't do this in Python 2.6+
    print err
    print err.args
    quit(0)

Nếu bạn thấy gán dấu phẩy trong codebase của mình và bạn đang sử dụng Python 2.5 trở lên, hãy chuyển sang cách làm mới để mã của bạn vẫn tương thích khi bạn nâng cấp.

Các suppress quản lý ngữ cảnh

Câu trả lời được chấp nhận thực sự là 4 dòng mã, tối thiểu:

try:
    do_something()
except (IDontLikeYouException, YouAreBeingMeanException) as e:
    pass

Các try, except, pass dòng có thể được xử lý trong một dòng với ngăn chặn trình quản lý ngữ cảnh, có sẵn trong Python 3.4:

from contextlib import suppress

with suppress(IDontLikeYouException, YouAreBeingMeanException):
     do_something()

Vì vậy, khi bạn muốn pass về một số ngoại lệ nhất định, sử dụng suppress.


186
2018-06-21 04:20



Câu trả lời hoàn chỉnh nhất. Người duy nhất chỉ định cách sử dụng except (KeyboardInterrupt, EOFError): cú pháp. - Eduard Luca


Đối với phiên bản python 2.5 và phiên bản cũ hơn, cú pháp chính xác là:

except (IDontLikeYouException, YouAreBeingMeanException), e:
    print e

Ở đâu e là trường hợp Ngoại lệ.


49
2018-05-13 12:37



Bạn không nên gán e bằng dấu phẩy nếu bạn muốn mã tương thích về phía trước và Python 2.5 không còn được cập nhật: mail.python.org/pipermail/python-committers/2011-October/… - Aaron Hall♦
có, nhưng với python 2.5 không có cách nào khác. Giải pháp tuyên bố rõ ràng phiên bản (cũ). - Jean-François Fabre


Từ Tài liệu Python -> Xử lý ngoại lệ 8.3:

A try câu lệnh có thể có nhiều hơn một mệnh đề ngoại trừ, để xác định   các trình xử lý cho các ngoại lệ khác nhau. Tối đa một người xử lý sẽ   Thực thi. Trình xử lý chỉ xử lý các ngoại lệ xảy ra trong   điều khoản thử tương ứng, không phải trong các trình xử lý khác của cùng một lần thử   tuyên bố. Một mệnh đề ngoại trừ có thể đặt tên cho nhiều ngoại lệ như một   tuple ngoặc đơn, ví dụ:

except (RuntimeError, TypeError, NameError):
    pass

Lưu ý rằng các dấu ngoặc đơn xung quanh bộ dữ liệu này là bắt buộc, bởi vì   ngoại trừ ValueError, e: là cú pháp được sử dụng cho những gì bình thường   Viết như except ValueError as e: trong Python hiện đại (được mô tả   phía dưới). Cú pháp cũ vẫn được hỗ trợ cho khả năng tương thích ngược.   Điều này có nghĩa là except RuntimeError, TypeError không tương đương với    except (RuntimeError, TypeError): nhưng để except RuntimeError as TypeError: đó không phải là những gì bạn muốn.


37
2017-10-30 10:01





Nếu bạn thường xuyên sử dụng một số lượng lớn ngoại lệ, bạn có thể xác định trước một bộ tuple, do đó bạn không phải nhập lại nhiều lần.

#This example code is a technique I use in a library that connects with websites to gather data

ConnectErrs  = (URLError, SSLError, SocketTimeoutError, BadStatusLine, ConnectionResetError)

def connect(url, data):
    #do connection and return some data
    return(received_data)

def some_function(var_a, var_b, ...):
    try: o = connect(url, data)
    except ConnectErrs as e:
        #do the recovery stuff
    blah #do normal stuff you would do if no exception occurred

GHI CHÚ: 

  1. Nếu bạn cũng cần nắm bắt các ngoại lệ khác với các trường hợp ngoại lệ được xác định trước tuple, bạn sẽ cần phải xác định một khối khác.

  2. Nếu bạn không thể chịu đựng được biến toàn cục, hãy xác định nó trong chính () và vượt qua nó khi cần ...


15
2017-09-18 01:36





Một trong những cách để làm điều này là ..

try:
   You do your operations here;
   ......................
except(Exception1[, Exception2[,...ExceptionN]]]):
   If there is any exception from the given exception list, 
   then execute this block.
   ......................
else:
   If there is no exception then execute this block. 

và một cách khác là tạo phương thức thực hiện tác vụ được thực hiện bởi except chặn và gọi nó qua tất cả except khối mà bạn viết ..

try:
   You do your operations here;
   ......................
except Exception1:
    functionname(parameterList)
except Exception2:
    functionname(parameterList)
except Exception3:
    functionname(parameterList)
else:
   If there is no exception then execute this block. 

def functionname( parameters ):
   //your task..
   return [expression]

Tôi biết rằng thứ hai không phải là cách tốt nhất để làm điều này, nhưng tôi chỉ hiển thị số cách để làm điều này.


5
2017-08-17 11:56





Python 2.7 Tài liệu tuyên bố rằng:

Một câu lệnh thử có thể có nhiều hơn một mệnh đề ngoại trừ, để xác định   các trình xử lý cho các ngoại lệ khác nhau. Tối đa một người xử lý sẽ   Thực thi. Trình xử lý chỉ xử lý các ngoại lệ xảy ra trong   điều khoản thử tương ứng, không phải trong các trình xử lý khác của cùng một lần thử   tuyên bố. Một mệnh đề ngoại trừ có thể đặt tên cho nhiều ngoại lệ như một   tuple ngoặc đơn, ví dụ:

try:
    raise ValueError("hello")
except (RuntimeError, ValueError, KeyError) as a:
    print a

chú thích   rằng các dấu ngoặc đơn xung quanh bộ dữ liệu này là bắt buộc, bởi vì ngoại trừ   ValueError, e: là cú pháp được sử dụng cho những gì thường được viết như   ngoại trừ ValueError như e: trong Python hiện đại (được mô tả bên dưới). Người già   cú pháp vẫn được hỗ trợ cho khả năng tương thích ngược. Điều này có nghĩa là   ngoại trừ RuntimeError, TypeError không tương đương ngoại trừ   (RuntimeError, TypeError): nhưng ngoại trừ RuntimeError là TypeError:   đó không phải là những gì bạn muốn.


3
2017-12-05 14:05