raiseExceptionfromexcの"from"
1
fromなし
except文中で他の例外をraiseするパターン.
try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

raise TypeError('except文中のTypeError')

結果
Traceback (most recent call last):

File "<stdin>", line 2, in <module>

ValueError: 一つ目のValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "<stdin>", line 4, in <module>

TypeError: except文中のTypeErrorr

2
fromなし
fromをつける場合
try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

raise TypeError('except文中のTypeError') from exc

結果
Traceback (most recent call last):

File "<stdin>", line 2, in <module>

ValueError: 一つ目のValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "<stdin>", line 4, in <module>

TypeError: except文中のTypeError

3
真ん中のメッセージに注目
fromなし
Duringhandlingoftheaboveexception,anotherexceptionoccurred:
fromあり
Theaboveexceptionwasthedirectcauseofthefollowingexception:
4
Exceptionクラスにセットされる属性が変わる.
先程の例外を変換する処理を関数にまとめる。(fromなし)
def create_exc_no_from():

try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

raise TypeError('except文中のTypeError')

例外クラスをキャッチしてみる。
try:

create_exc_no_from()

except Exception as exc:

result = exc

5
Exceptionクラスにセットされる属性が変わる(fromなし)
>>> result.__cause__ # None

>>> result.__context__

ValueError('一つ目のValueError')

>>> result.__suppress_context__

False

6
Exceptionクラスにセットされる属性が変わる.
先程の例外を変換する処理を関数にまとめる。(fromあり)
def create_exc_with_from():

try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

raise TypeError('except文中のTypeError') from exc

例外クラスをキャッチしてみる。
try:

create_exc_with_from()

except Exception as exc:

result = exc

7
Exceptionクラスにセットされる属性が変わる(fromあり)
>>> result.__cause__ # None から変更

ValueError('一つ目のValueError')

>>> result.__context__

ValueError('一つ目のValueError')

>>> result.__suppress_context__ # False から変更

True

8
まとめ
@ fromなし fromあり
__cause__ None ValueError
__context__ ValueError ValueError
__supress_context__ False True
9
なぜ必要か
意図して行った例外の変換と、うっかりexcept文中で出てしまった例外を区別できる。
例外表示の仕組みを細かくカスタムできる
10
なぜ必要か
def create_exc_with_from():

try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

tmp = 1 / 0 # うっかり0割の処理をしてしまった.

raise TypeError('except文中のTypeError') from exc

create_exc_with_from()

Traceback (most recent call last):

File "<stdin>", line 3, in create_exc_with_from

ValueError: 一つ目のValueError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "<stdin>", line 1, in <module>

File "<stdin>", line 5, in create_exc_with_from

ZeroDivisionError: division by zero
 11
なぜひつようか
def create_exc_with_from():

try:

raise ValueError('一つ目のValueError')

except ValueError as exc:

raise TypeError('except文中のTypeError') from exc

try:

create_exc_with_from()

except Exception as exc:

raise KeyError('3つめの例外') from exc.__cause__

12
1つめの例外が3つめの例外の直接の原因だと示すことがで
きる.
Traceback (most recent call last)

File "<stdin>", line 3, in create_exc_with_from

ValueError: 一つ目のValueError

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

File "<stdin>", line 4, in <module>

KeyError: '3つめの例外'

参考:このstackoverflowのコメントやりとり部分.

https://stackoverflow.com/questions/24752395/python-raise-from-usage
13
他
scrapboxに参考にしたリンクをまとめておきました。

https://scrapbox.io/geeklabnagano-43207315/📕_Effective_Python_読書会_%2320
14

個人メモ用(Pythonのexceptionをfromでかく理由)