รับค่าข้อยกเว้นใน Python


239

หากฉันมีรหัสนั้น:

try:
    some_method()
except Exception, e:

ฉันจะรับค่าข้อยกเว้นนี้ได้อย่างไร (การแทนค่าสตริงที่ฉันหมายถึง)

คำตอบ:


323

ใช้ str

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

นอกจากนี้คลาสยกเว้นส่วนใหญ่จะมีargsแอตทริบิวต์ บ่อยครั้งargs[0]จะเป็นข้อความแสดงข้อผิดพลาด

ควรสังเกตว่าการใช้เพียงแค่strจะส่งคืนสตริงว่างถ้าไม่มีข้อความแสดงข้อผิดพลาดในขณะที่ใช้reprเป็น pyfunc แนะนำอย่างน้อยจะแสดงชั้นของข้อยกเว้น สิ่งที่ฉันต้องทำคือถ้าคุณพิมพ์ออกมาสำหรับผู้ใช้ที่ไม่สนใจว่าคลาสคืออะไรและต้องการข้อความแสดงข้อผิดพลาด

มันขึ้นอยู่กับคลาสของข้อยกเว้นที่คุณจัดการและวิธีการสร้างอินสแตนซ์ คุณมีอะไรเป็นพิเศษในใจหรือไม่?


ฉันกำลังพิมพ์เพื่อทำรายงาน str (e) ก็ดีฉันเดา ขอบคุณมาก
Frias

8
ฉันต้องการใช้e.messageเพราะargs[0]อาจไม่ใช่ข้อความจริง
cedbeu

3
repr (e) มีประโยชน์เช่นกันหากคุณต้องการได้รับการยกเว้นแบบเต็ม (เช่น NameError ("ชื่อโกลบอล 'ตัวแปร' ไม่ได้ถูกกำหนด",), แทนที่จะเป็น "ชื่อโกลบอล 'ตัวแปร' ไม่ได้ถูกกำหนด"
Ben Morris

49
คำตอบนี้เป็นอันตรายตามที่มันจะล้มเหลวสำหรับข้อยกเว้น Unicode raise Exception(u'jörn')เช่นนี้ ความล้มเหลวที่ไม่ดีโดยเฉพาะอย่างยิ่งเพราะคุณจะไม่เคยเห็นข้อยกเว้นที่เกิดขึ้นจริง UnicodeDecodeErrorแต่เป็นเพียงแค่ หากคุณไม่ทราบว่าการเข้ารหัสของข้อยกเว้น (และส่วนใหญ่เวลาที่คุณไม่ได้) คุณควรจะทำงานrepr(e)หรือถ้าคุณต้องการจริงๆให้ใช้บล็อกลองยกเว้นอื่นในการจัดการข้อยกเว้นของคุณซึ่งจับ UnicodeDecodeErrors และกลับไปrepr(e).
Jörn Hees

11
เห็นด้วยกับ @ JörnHees ฉันไม่สามารถนับจำนวนครั้งที่str(หรือแม้กระทั่งunicodeหรือ.format) ได้ก่อให้เกิดข้อผิดพลาดที่เกิดจากการจัดการ Unicode หากคุณไม่มีการควบคุมเนื้อหาข้อความแสดงข้อผิดพลาดอย่างสมบูรณ์เสมอใช้reprเพื่อหลีกเลี่ยงข้อผิดพลาด Unicode ที่ไม่คาดคิด
Kenny Trytek

186

ใช้ repr () และความแตกต่างระหว่างการใช้ repr และ str

การใช้repr:

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

การใช้str:

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

2
อาreprขอบคุณประโยชน์ก็ดูเหมือนว่าสิ่งอื่นใดunicode, strเข้ารหัส ... อาจเพิ่มข้อยกเว้นทั้งนี้ขึ้นอยู่กับการป้อนข้อมูล ไม่ค่อยมีประโยชน์เมื่อพยายามเก็บข้อยกเว้นให้ดู แต่exception-safeดูเหมือนว่าจะมีการตอบกลับ
dashesy

2
นี้เป็นมากดีกว่าstr()การแก้ปัญหาเหมือนเพราะมันจริงรวมถึงประเภทของข้อยกเว้น เมื่อstr()ฉันได้รับ'status'ในขณะที่repr()ฉันได้รับKeyError('status')และฉันก็เหมือน "aaaaah ตอนนี้ฉันเข้าใจข้อผิดพลาด"
jlh

27

แม้ว่าฉันจะรู้ว่านี่เป็นคำถามเก่าฉันอยากจะแนะนำให้ใช้tracebackโมดูลเพื่อจัดการกับข้อยกเว้น

ใช้traceback.print_exc()เพื่อพิมพ์ข้อยกเว้นปัจจุบันเป็นข้อผิดพลาดมาตรฐานเช่นเดียวกับที่มันจะถูกพิมพ์หากมันยังไม่ได้ตรวจสอบหรือtraceback.format_exc()เพื่อให้ได้ผลลัพธ์เช่นเดียวกับสตริง คุณสามารถส่งอาร์กิวเมนต์ต่าง ๆ ไปยังฟังก์ชันเหล่านี้ได้หากคุณต้องการ จำกัด เอาต์พุตหรือเปลี่ยนทิศทางการพิมพ์ไปยังวัตถุที่มีลักษณะคล้ายไฟล์


23

ยังไม่ได้รับวิธีอื่น:

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

เอาท์พุท:

integer division or modulo by zero

args[0] อาจไม่ใช่ข้อความจริง

str(e)อาจส่งคืนสตริงที่มีเครื่องหมายคำพูดล้อมรอบและอาจเป็นผู้นำuถ้า Unicode:

'integer division or modulo by zero'

repr(e) ให้การแสดงข้อยกเว้นแบบเต็มซึ่งไม่น่าจะเป็นสิ่งที่คุณต้องการ:

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

แก้ไข

ความผิดฉันเอง !!! ดูเหมือนว่าBaseException.message เลิกใช้แล้ว2.6ในที่สุดดูเหมือนว่ายังไม่มีวิธีมาตรฐานในการแสดงข้อความยกเว้น ดังนั้นฉันคิดว่าดีที่สุดคือจัดการกับe.argsและstr(e)ขึ้นอยู่กับความต้องการของคุณ (และอาจเป็นไปได้e.messageว่า lib ที่คุณใช้นั้นขึ้นอยู่กับกลไกนั้น)

ยกตัวอย่างเช่นมีpygraphviz, e.messageเป็นวิธีเดียวที่จะแสดงอย่างถูกต้องข้อยกเว้นที่ใช้จะล้อมรอบข้อความด้วยstr(e)u''

แต่ด้วยMySQLdbวิธีที่เหมาะสมในการดึงข้อความคือe.args[1]: e.messageว่างเปล่าและstr(e)จะแสดงขึ้นมา'(ERR_CODE, "ERR_MSG")'


0

สำหรับ python2 มันจะดีกว่าที่จะใช้จะได้รับข้อความแสดงข้อยกเว้นนี้จะหลีกเลี่ยงไปได้e.message UnicodeDecodeErrorแต่ใช่e.messageจะว่างเปล่าสำหรับข้อยกเว้นบางประเภทเช่นOSErrorในกรณีนี้เราสามารถเพิ่มexc_info=Trueฟังก์ชันการบันทึกของเราเพื่อไม่ให้พลาดข้อผิดพลาด
สำหรับ python3 str(e)ผมคิดว่ามันปลอดภัยที่จะใช้


0

หากคุณไม่ทราบประเภท / ที่มาของข้อผิดพลาดคุณสามารถลอง:

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

แต่ระวังคุณจะได้รับคำเตือน pep8:

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

0

ในการตรวจสอบข้อความแสดงข้อผิดพลาดและทำบางสิ่งกับมัน (ด้วย Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.