คำตอบสำหรับคำถามนี้ขึ้นอยู่กับเวอร์ชันของ Python ที่คุณใช้
ใน Python 3
มันง่ายมาก: ข้อยกเว้นมาพร้อมกับ__traceback__
แอตทริบิวต์ที่มีการย้อนกลับ แอตทริบิวต์นี้สามารถเขียนได้และสามารถตั้งค่าได้อย่างสะดวกโดยใช้with_traceback
วิธีการยกเว้น:
raise Exception("foo occurred").with_traceback(tracebackobj)
คุณลักษณะเหล่านี้อธิบายสั้น ๆ เป็นส่วนหนึ่งของraise
เอกสารประกอบ
เครดิตทั้งหมดสำหรับส่วนหนึ่งของคำตอบนี้ควรจะไป Vyctor ที่แรกที่โพสต์ข้อมูลนี้ ฉันรวมไว้ที่นี่เท่านั้นเนื่องจากคำตอบนี้ติดอยู่ที่ด้านบนและ Python 3 ก็กลายเป็นเรื่องธรรมดามากขึ้น
ใน Python 2
มันซับซ้อนน่ารำคาญ ปัญหาในการย้อนกลับคือมีการอ้างอิงถึงสแต็กเฟรมและสแต็กเฟรมมีการอ้างอิงถึงการย้อนกลับที่มีการอ้างอิงถึงสแต็กเฟรมที่มีการอ้างอิงถึง ...คุณจะได้รับแนวคิด สิ่งนี้ทำให้เกิดปัญหากับคนเก็บขยะ (ขอบคุณecatmur ที่ชี้ให้เห็นเป็นครั้งแรก)
วิธีที่ดีในการแก้ปัญหานี้คือการผ่าตัดตัดวงจรหลังจากออกจากexcept
ข้อซึ่งเป็นสิ่งที่ Python 3 ทำ โซลูชัน Python 2 นั้นน่าเกลียดกว่ามาก: คุณได้รับฟังก์ชันเฉพาะกิจsys.exc_info()
ซึ่งใช้งานได้เฉพาะในส่วน except
คำสั่งเท่านั้น จะส่งคืนทูเพิลที่มีข้อยกเว้นประเภทข้อยกเว้นและการตรวจสอบย้อนกลับสำหรับข้อยกเว้นใด ๆ ที่กำลังจัดการอยู่
ดังนั้นหากคุณอยู่ในexcept
อนุประโยคคุณสามารถใช้ผลลัพธ์ของsys.exc_info()
พร้อมกับtraceback
โมดูลเพื่อทำสิ่งต่างๆที่เป็นประโยชน์:
>>> import sys, traceback
>>> def raise_exception():
... try:
... raise Exception
... except Exception:
... ex_type, ex, tb = sys.exc_info()
... traceback.print_tb(tb)
... finally:
... del tb
...
>>> raise_exception()
File "<stdin>", line 3, in raise_exception
แต่ในขณะที่การแก้ไขของคุณบ่งชี้ว่าคุณกำลังพยายามที่จะได้รับ traceback ที่จะได้รับการตีพิมพ์ถ้าข้อยกเว้นของคุณไม่ได้รับการจัดการหลังจากที่มันได้แล้วรับการจัดการ นั่นเป็นคำถามที่ยากกว่ามาก น่าเสียดายที่sys.exc_info
ส่งคืน(None, None, None)
เมื่อไม่มีการจัดการข้อยกเว้น sys
แอตทริบิวต์อื่น ๆ ที่เกี่ยวข้องก็ไม่ช่วยเช่นกัน sys.exc_traceback
เลิกใช้งานและไม่ได้กำหนดเมื่อไม่มีการจัดการข้อยกเว้น sys.last_traceback
ดูเหมือนจะสมบูรณ์แบบ แต่ดูเหมือนจะกำหนดเฉพาะในช่วงการโต้ตอบเท่านั้น
หากคุณสามารถควบคุมวิธีเพิ่มข้อยกเว้นคุณอาจสามารถใช้inspect
และข้อยกเว้นที่กำหนดเองเพื่อจัดเก็บข้อมูลบางส่วน แต่ฉันไม่แน่ใจทั้งหมดว่าจะได้ผลอย่างไร
เพื่อบอกความจริงการจับและส่งคืนข้อยกเว้นถือเป็นเรื่องผิดปกติที่ต้องทำ นี่อาจเป็นสัญญาณว่าคุณต้องทำการ refactor อยู่ดี