私はこのようにしたいので、タイプを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の場合、最初の更新のコードは構文的に正しくありません。また、2012-05-16のPEP 352への変更で、message
属性をオンBaseException
にするという考えが撤回されました(私の最初の更新は2012-03-12に投稿されました)。 。したがって、現在のところ、Python 3.5.2ではとにかく、トレースバックを保持し、関数の例外のタイプをハードコードしないように、これらの行に沿って何かを行う必要があります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
答えが原因構文の違いに「いいえ」のように見えるかもしれませんが、Pythonの2と3の両方で動作するような方法があった場合コメンターが尋ね、そこにあるようにヘルパー関数を使用して、その周りのやり方reraise()
でsix
アドインはモジュール上。そのため、何らかの理由でライブラリを使用したくない場合は、以下に簡略化されたスタンドアロンバージョンを示します。
また、例外は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
属性のドキュメントを探しているときに、このSOの質問を見つけました。BaseException.messageはPython 2.6で非推奨になりました。これは、その使用が現在推奨されていないことを示しているようです(ドキュメントに含まれていない理由です)。