Lấy giá trị ngoại lệ trong Python


239

Nếu tôi có mã đó:

try:
    some_method()
except Exception, e:

Làm thế nào tôi có thể nhận được giá trị Ngoại lệ này (ý tôi là đại diện chuỗi)?

Câu trả lời:


323

sử dụng str

try:
    some_method()
except Exception as e:
    s = str(e)

Ngoài ra, hầu hết các lớp ngoại lệ sẽ có một argsthuộc tính. Thông thường, args[0]sẽ là một thông báo lỗi.

Cần lưu ý rằng chỉ cần sử dụng strsẽ trả về một chuỗi rỗng nếu không có thông báo lỗi trong khi sử dụng reprnhư pyfunc khuyến nghị ít nhất sẽ hiển thị lớp ngoại lệ. Tôi xin lưu ý rằng nếu bạn in nó ra, nó dành cho người dùng cuối không quan tâm lớp đó là gì và chỉ muốn một thông báo lỗi.

Nó thực sự phụ thuộc vào lớp ngoại lệ mà bạn đang xử lý và cách nó được khởi tạo. Bạn đã có một cái gì đó đặc biệt trong tâm trí?


Tôi đang in cái này để làm báo cáo, tôi đoán là str (e) vẫn ổn. Cảm ơn rất nhiều
Frias

8
Tôi muốn sử dụng e.messageargs[0]có thể không thực sự là một tin nhắn.
cedbeu

3
repr (e) cũng hữu ích nếu bạn muốn có được ngoại lệ đầy đủ (ví dụ: NameError ("tên toàn cầu 'biến' không được xác định",), thay vì "biến toàn cầu 'không được xác định"
Ben Morris

49
Câu trả lời này rất nguy hiểm, vì nó sẽ thất bại đối với các ngoại lệ unicode như thế này : raise Exception(u'jörn'). Thất bại là đặc biệt xấu, bởi vì bạn sẽ không bao giờ thấy ngoại lệ thực tế mà chỉ là a UnicodeDecodeError. Nếu bạn không biết mã hóa ngoại lệ (và hầu hết thời gian bạn không sử dụng), bạn nên làm việc repr(e)hoặc nếu bạn thực sự cần, sử dụng một khối ngoại trừ thử khác trong xử lý ngoại lệ của bạn để bắt UnicodeDecodeErrors và quay lại repr(e).
Jorn Hees

11
Đồng ý với @ JornHees. Tôi không thể đếm số lần str(hoặc thậm chí unicodehoặc .format) đã gây ra lỗi do xử lý Unicode. Nếu bạn không có quyền kiểm soát hoàn toàn nội dung thông báo lỗi, LUÔN LUÔN sử dụng reprđể tránh các lỗi Unicode không mong muốn.
Kenny Trytek

185

Sử dụng repr () và Sự khác biệt giữa sử dụng repr và str

Sử dụng repr:

>>> try:
...     print(x)
... except Exception as e:
...     print(repr(e))
... 
NameError("name 'x' is not defined")

Sử dụng str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined

2
ah, reprrất hữu ích nhờ, có vẻ như bất cứ điều gì khác unicode, str, mã hóa, ... có thể nâng một ngoại lệ tùy thuộc vào đầu vào. Không hoàn toàn hữu ích khi cố gắng giữ ngoại lệ để nhìn, nhưng exception-safedường như repr
bảnh bao

2
Đây là nhiều hơn so với bất kỳ str()giải pháp -like, bởi vì nó thực sự bao gồm các loại ngoại lệ. Với str()tôi đã có 'status'trong khi repr()tôi có KeyError('status')và tôi giống như "aaaaah, bây giờ tôi đã hiểu lỗi".
jlh

27

Mặc dù tôi nhận ra đây là một câu hỏi cũ, tôi muốn đề xuất sử dụng tracebackmô-đun để xử lý đầu ra của các ngoại lệ.

Sử dụng traceback.print_exc()để in ngoại lệ hiện tại đối với lỗi tiêu chuẩn, giống như nó sẽ được in nếu nó vẫn chưa được xử lý hoặc traceback.format_exc()để có cùng một đầu ra như một chuỗi. Bạn có thể chuyển các đối số khác nhau cho một trong các hàm đó nếu bạn muốn giới hạn đầu ra hoặc chuyển hướng in sang một đối tượng giống như tệp.


23

Một cách khác chưa được đưa ra:

try:
    1/0
except Exception, e:
    print e.message

Đầu ra:

integer division or modulo by zero

args[0] thực sự có thể không phải là một tin nhắn.

str(e)có thể trả về chuỗi với các dấu ngoặc kép xung quanh và có thể là hàng đầu unếu unicode:

'integer division or modulo by zero'

repr(e) đưa ra đại diện ngoại lệ đầy đủ mà có lẽ không phải là những gì bạn muốn:

"ZeroDivisionError('integer division or modulo by zero',)"

biên tập

Lỗi của tôi !!! Dường như BaseException.message đã bị từ chối2.6 , cuối cùng, dường như vẫn chưa có một cách tiêu chuẩn nào để hiển thị các thông báo ngoại lệ. Vì vậy, tôi đoán tốt nhất là giải quyết e.argsstr(e)tùy thuộc vào nhu cầu của bạn (và có thể e.messagenếu lib bạn đang sử dụng đang dựa vào cơ chế đó).

Ví dụ, với pygraphviz, e.messagelà cách duy nhất để hiển thị chính xác ngoại lệ, sử dụng str(e)sẽ bao quanh thư với u''.

Nhưng với MySQLdb, cách thích hợp để truy xuất thư là e.args[1]: e.messagetrống và str(e)sẽ hiển thị'(ERR_CODE, "ERR_MSG")'


0

Đối với python2, tốt hơn là sử dụng e.messageđể nhận thông báo ngoại lệ, điều này sẽ tránh được UnicodeDecodeError. Nhưng có e.messagesẽ trống đối với một số loại ngoại lệ như OSError, trong trường hợp đó chúng ta có thể thêm một exc_info=Truechức năng ghi nhật ký để không bỏ lỡ lỗi.
Đối với python3, tôi nghĩ nó an toàn khi sử dụng str(e).


0

Nếu bạn không biết loại / nguồn gốc của lỗi, bạn có thể thử:

import sys
try:
    doSomethingWrongHere()
except:
    print('Error: {}'.format(sys.exc_info()[0]))

Nhưng hãy lưu ý, bạn sẽ nhận được cảnh báo pep8:

[W] PEP 8 (E722): do not use bare except

0

Để kiểm tra thông báo lỗi và làm gì đó với nó (với Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.