ฉันต้องการทำเช่นนี้ดังนั้นการเปลี่ยนประเภทในfoo()
ไม่จำเป็นต้องเปลี่ยนมันbar()
ด้วย
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
raise type(e)(e.message + ' happens at %s' % arg1)
bar('arg1')
Traceback (most recent call last):
File "test.py", line 13, in <module>
bar('arg1')
File "test.py", line 11, in bar
raise type(e)(e.message + ' happens at %s' % arg1)
IOError: Stuff happens at arg1
อัปเดต 1
นี่คือการปรับเปลี่ยนเล็กน้อยที่เก็บรักษาย้อนกลับดั้งเดิม:
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e), type(e)(e.message +
' happens at %s' % arg1), sys.exc_info()[2]
bar('arg1')
Traceback (most recent call last):
File "test.py", line 16, in <module>
bar('arg1')
File "test.py", line 11, in bar
foo()
File "test.py", line 5, in foo
raise IOError('Stuff')
IOError: Stuff happens at arg1
อัปเดต 2
สำหรับ Python 3.x รหัสในการอัปเดตครั้งแรกของฉันนั้นไม่ถูกต้องทางวากยสัมพันธ์บวกกับความคิดที่ว่าจะมีการเปิดใช้message
คุณลักษณะBaseException
นั้นในการเปลี่ยนเป็น PEP 352ใน 2012-05-16 (อัปเดตครั้งแรกของฉันเมื่อวันที่ 2012-03-12) . ดังนั้นในปัจจุบันในหลาม 3.5.2 แล้วคุณจะต้องทำอะไรบางอย่างตามบรรทัดเหล่านี้เพื่อรักษา traceback และไม่ hardcode bar()
ประเภทของข้อยกเว้นในการทำงาน โปรดทราบว่าจะมีบรรทัด:
During handling of the above exception, another exception occurred:
ในข้อความย้อนกลับที่ปรากฏขึ้น
# for Python 3.x
...
def bar(arg1):
try:
foo()
except Exception as e:
import sys
raise type(e)(str(e) +
' happens at %s' % arg1).with_traceback(sys.exc_info()[2])
bar('arg1')
อัปเดต 3
commenter ถามว่ามีวิธีการที่จะทำงานทั้งในหลาม 2 และ 3 ถึงแม้ว่าคำตอบอาจดูเหมือนจะ "ไม่" เนื่องจากความแตกต่างไวยากรณ์มีเป็นทางรอบว่าด้วยการใช้ฟังก์ชั่นผู้ช่วยเหมือนreraise()
ในsix
Add- ในโมดูล ดังนั้นหากคุณไม่ต้องการใช้ห้องสมุดด้วยเหตุผลบางอย่างด้านล่างเป็นเวอร์ชั่นสแตนด์อโลนที่ง่ายขึ้น
โปรดทราบด้วยเช่นกันว่าเนื่องจากมีการยกเว้นข้อยกเว้นภายในreraise()
ฟังก์ชันที่จะปรากฏในสิ่งที่เพิ่มกลับ แต่ผลลัพธ์สุดท้ายคือสิ่งที่คุณต้องการ
import sys
if sys.version_info.major < 3: # Python 2?
# Using exec avoids a SyntaxError in Python 3.
exec("""def reraise(exc_type, exc_value, exc_traceback=None):
raise exc_type, exc_value, exc_traceback""")
else:
def reraise(exc_type, exc_value, exc_traceback=None):
if exc_value is None:
exc_value = exc_type()
if exc_value.__traceback__ is not exc_traceback:
raise exc_value.with_traceback(exc_traceback)
raise exc_value
def foo():
try:
raise IOError('Stuff')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
reraise(type(e), type(e)(str(e) +
' happens at %s' % arg1), sys.exc_info()[2])
bar('arg1')
message
แอตทริบิวต์Exception ฉันพบคำถาม SO นี้BaseException.message เลิกใช้ใน Python 2.6ซึ่งดูเหมือนว่าจะบ่งบอกว่าการใช้งานนั้นไม่ได้รับการสนับสนุนในขณะนี้ (และทำไมจึงไม่อยู่ในเอกสาร)