Python の contextlib.suppress で例外を無視する

contextlib.suppress() は、特定の例外を無視して処理を続行するためのコンテキストマネージャです。try-exceptpass するパターンを簡潔に書けます。

基本的な使い方

指定した例外が発生しても、何事もなかったかのように処理が続行されます。

from contextlib import suppress

with suppress(FileNotFoundError):
    open("存在しないファイル.txt")

print("処理継続")  # 例外があっても実行される

try-except との比較

suppress()

1行で簡潔に書ける。例外を完全に無視する。

try-except

より細かい制御が可能。except ブロックで処理を追加できる。

# try-except の場合
try:
    open("存在しないファイル.txt")
except FileNotFoundError:
    pass

# suppress の場合
from contextlib import suppress

with suppress(FileNotFoundError):
    open("存在しないファイル.txt")

複数の例外を指定

複数の例外を同時に指定できます。

from contextlib import suppress

with suppress(FileNotFoundError, PermissionError):
    # どちらの例外が発生しても無視される
    open("/root/secret.txt")

print("処理継続")

実用例:ファイル削除

ファイルが存在しない場合でもエラーにならないようにします。

import os
from contextlib import suppress

# ファイルがなくてもエラーにならない
with suppress(FileNotFoundError):
    os.remove("temp.txt")

# 従来の書き方
if os.path.exists("temp.txt"):
    os.remove("temp.txt")

suppress() を使う方が、レースコンディション(存在確認と削除の間にファイルが消える可能性)を避けられます。

実用例:辞書のキー削除

KeyError を無視してキーを削除します。

from contextlib import suppress

data = {"a": 1, "b": 2}

with suppress(KeyError):
    del data["c"]  # 存在しないキーでもエラーにならない

print(data)  # {'a': 1, 'b': 2}

ただし、辞書の場合は pop() のデフォルト値を使う方が一般的です。

data.pop("c", None)  # こちらの方がシンプル

実用例:型変換

変換に失敗した場合のデフォルト値を設定します。

from contextlib import suppress

def safe_int(value, default=0):
    with suppress(ValueError, TypeError):
        return int(value)
    return default

print(safe_int("123"))      # 123
print(safe_int("abc"))      # 0
print(safe_int(None))       # 0
print(safe_int("xyz", -1))  # -1

注意点

suppress() は例外を完全に無視するため、使いすぎるとバグの発見が困難になります。

from contextlib import suppress

# 悪い例:すべての例外を無視
with suppress(Exception):
    result = dangerous_operation()
    # 何が起きても無視されてしまう

抑制する例外は必要最小限にし、なぜ無視しても安全なのかをコメントで説明することをおすすめします。

from contextlib import suppress

# ファイルが存在しない場合は無視して良い(初回実行時など)
with suppress(FileNotFoundError):
    os.remove("cache.txt")

suppress() は「例外が発生しても問題ない」ことが明確な場合にのみ使いましょう。