หากฉันมีรหัสนั้น:
try:
some_method()
except Exception, e:
ฉันจะรับค่าข้อยกเว้นนี้ได้อย่างไร (การแทนค่าสตริงที่ฉันหมายถึง)
หากฉันมีรหัสนั้น:
try:
some_method()
except Exception, e:
ฉันจะรับค่าข้อยกเว้นนี้ได้อย่างไร (การแทนค่าสตริงที่ฉันหมายถึง)
คำตอบ:
ใช้ str
try:
some_method()
except Exception as e:
s = str(e)
นอกจากนี้คลาสยกเว้นส่วนใหญ่จะมีargsแอตทริบิวต์ บ่อยครั้งargs[0]จะเป็นข้อความแสดงข้อผิดพลาด
ควรสังเกตว่าการใช้เพียงแค่strจะส่งคืนสตริงว่างถ้าไม่มีข้อความแสดงข้อผิดพลาดในขณะที่ใช้reprเป็น pyfunc แนะนำอย่างน้อยจะแสดงชั้นของข้อยกเว้น สิ่งที่ฉันต้องทำคือถ้าคุณพิมพ์ออกมาสำหรับผู้ใช้ที่ไม่สนใจว่าคลาสคืออะไรและต้องการข้อความแสดงข้อผิดพลาด
มันขึ้นอยู่กับคลาสของข้อยกเว้นที่คุณจัดการและวิธีการสร้างอินสแตนซ์ คุณมีอะไรเป็นพิเศษในใจหรือไม่?
e.messageเพราะargs[0]อาจไม่ใช่ข้อความจริง
raise Exception(u'jörn')เช่นนี้ ความล้มเหลวที่ไม่ดีโดยเฉพาะอย่างยิ่งเพราะคุณจะไม่เคยเห็นข้อยกเว้นที่เกิดขึ้นจริง UnicodeDecodeErrorแต่เป็นเพียงแค่ หากคุณไม่ทราบว่าการเข้ารหัสของข้อยกเว้น (และส่วนใหญ่เวลาที่คุณไม่ได้) คุณควรจะทำงานrepr(e)หรือถ้าคุณต้องการจริงๆให้ใช้บล็อกลองยกเว้นอื่นในการจัดการข้อยกเว้นของคุณซึ่งจับ UnicodeDecodeErrors และกลับไปrepr(e).
str(หรือแม้กระทั่งunicodeหรือ.format) ได้ก่อให้เกิดข้อผิดพลาดที่เกิดจากการจัดการ Unicode หากคุณไม่มีการควบคุมเนื้อหาข้อความแสดงข้อผิดพลาดอย่างสมบูรณ์เสมอใช้reprเพื่อหลีกเลี่ยงข้อผิดพลาด Unicode ที่ไม่คาดคิด
ใช้ 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
reprขอบคุณประโยชน์ก็ดูเหมือนว่าสิ่งอื่นใดunicode, strเข้ารหัส ... อาจเพิ่มข้อยกเว้นทั้งนี้ขึ้นอยู่กับการป้อนข้อมูล ไม่ค่อยมีประโยชน์เมื่อพยายามเก็บข้อยกเว้นให้ดู แต่exception-safeดูเหมือนว่าจะมีการตอบกลับ
str()การแก้ปัญหาเหมือนเพราะมันจริงรวมถึงประเภทของข้อยกเว้น เมื่อstr()ฉันได้รับ'status'ในขณะที่repr()ฉันได้รับKeyError('status')และฉันก็เหมือน "aaaaah ตอนนี้ฉันเข้าใจข้อผิดพลาด"
แม้ว่าฉันจะรู้ว่านี่เป็นคำถามเก่าฉันอยากจะแนะนำให้ใช้tracebackโมดูลเพื่อจัดการกับข้อยกเว้น
ใช้traceback.print_exc()เพื่อพิมพ์ข้อยกเว้นปัจจุบันเป็นข้อผิดพลาดมาตรฐานเช่นเดียวกับที่มันจะถูกพิมพ์หากมันยังไม่ได้ตรวจสอบหรือtraceback.format_exc()เพื่อให้ได้ผลลัพธ์เช่นเดียวกับสตริง คุณสามารถส่งอาร์กิวเมนต์ต่าง ๆ ไปยังฟังก์ชันเหล่านี้ได้หากคุณต้องการ จำกัด เอาต์พุตหรือเปลี่ยนทิศทางการพิมพ์ไปยังวัตถุที่มีลักษณะคล้ายไฟล์
ยังไม่ได้รับวิธีอื่น:
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")'
สำหรับ python2 มันจะดีกว่าที่จะใช้จะได้รับข้อความแสดงข้อยกเว้นนี้จะหลีกเลี่ยงไปได้e.message UnicodeDecodeErrorแต่ใช่e.messageจะว่างเปล่าสำหรับข้อยกเว้นบางประเภทเช่นOSErrorในกรณีนี้เราสามารถเพิ่มexc_info=Trueฟังก์ชันการบันทึกของเราเพื่อไม่ให้พลาดข้อผิดพลาด
สำหรับ python3 str(e)ผมคิดว่ามันปลอดภัยที่จะใช้
หากคุณไม่ทราบประเภท / ที่มาของข้อผิดพลาดคุณสามารถลอง:
import sys
try:
doSomethingWrongHere()
except:
print('Error: {}'.format(sys.exc_info()[0]))
แต่ระวังคุณจะได้รับคำเตือน pep8:
[W] PEP 8 (E722): do not use bare except
ในการตรวจสอบข้อความแสดงข้อผิดพลาดและทำบางสิ่งกับมัน (ด้วย Python 3) ...
try:
some_method()
except Exception as e:
if {value} in e.args:
{do something}