Tôi sẽ làm như thế này để thay đổi loại của nó foo()
sẽ không yêu cầu thay đổi nó trong 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
Cập nhật 1
Đây là một sửa đổi nhỏ để duy trì truy nguyên gốc:
...
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
Cập nhật 2
Đối với Python 3.x, mã trong bản cập nhật đầu tiên của tôi về mặt cú pháp không chính xác cộng với ý tưởng có một message
thuộc tính trên BaseException
được rút lại trong một thay đổi thành PEP 352 vào ngày 2012-05-16 (bản cập nhật đầu tiên của tôi đã được đăng vào ngày 2012 / 03-12) . Vì vậy, hiện tại, trong Python 3.5.2, bạn cần phải làm gì đó dọc theo các dòng này để duy trì truy nguyên và không mã hóa loại ngoại lệ trong hàm bar()
. Cũng lưu ý rằng sẽ có dòng:
During handling of the above exception, another exception occurred:
trong các thông báo truy nguyên được hiển thị.
# 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')
Cập nhật 3
Một commenter hỏi nếu có một cách mà có thể làm việc trong cả hai Python 2 và 3. Mặc dù câu trả lời có vẻ là "Không" do sự khác biệt cú pháp, có là một con đường xung quanh đó bằng cách sử dụng một hàm helper như reraise()
trongsix
Add- trên mô-đun. Vì vậy, nếu bạn không muốn sử dụng thư viện vì một số lý do, dưới đây là phiên bản độc lập đơn giản hóa.
Lưu ý rằng, vì ngoại lệ được phát lại trong reraise()
hàm, nó sẽ xuất hiện trong bất kỳ dấu vết nào được đưa ra, nhưng kết quả cuối cùng là những gì bạn muốn.
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
thuộc tính Exception, tôi đã tìm thấy câu hỏi SO này, BaseException.message không dùng nữa trong Python 2.6 , điều này dường như cho thấy việc sử dụng nó hiện không được khuyến khích (và tại sao nó không có trong tài liệu).