Tech カテゴリのイメージ

TypeError: 'NoneType' object is not subscriptable の対処

このエラーは、None が入っている変数に対して x[0]x["key"] のような添字アクセスをしたときに出ます。直接の原因は明快で、その変数がNoneだったこと。本当の問題は「なぜNoneが入ったか」で、Noneを返す関数(re.match、dict.get、findなど)の戻り値を確認せずに使っているのが典型です。

TypeError: 'NoneType' object is not subscriptable

原因

Pythonでは「見つからなかった」「該当なし」をNoneで返す関数が多くあります。代表例は次のとおりです。

・re.match / re.search(マッチしないとNone) ・dict.get(“key”)(キーがないとNone) ・BeautifulSoupの find(要素がないとNone) ・戻り値のない関数(returnを書き忘れるとNone)

これらの戻り値をそのまま [ ] で触ると、該当なしのケースでこのエラーになります。

対処

  1. トレースバックの行番号を見て、どの変数がNoneかを特定します。迷ったら直前にprintを入れます。
m = re.match(r"(\d+)", text)
print(m) # None ならマッチしていない
  1. Noneの可能性がある戻り値は、使う前に分岐します。
m = re.match(r"(\d+)", text)
if m:
num = m[1]
else:
num = None # 見つからないときの扱いを決める
  1. 辞書は get の第2引数で既定値を渡すと、None分岐そのものを消せます。
value = config.get("timeout", 30)
  1. 自作関数が原因の場合は、全経路でreturnしているかを確認します。if分岐の片側でreturnを忘れると、その経路はNoneを返します。

まとめ

・直接の原因はNoneへの添字アクセス。真因は「Noneを返す関数の戻り値を未確認で使う」こと ・re.match / dict.get / find などはNoneを返しうる ・使う前にif分岐、辞書はget(key, default)で既定値を渡す ・自作関数はreturn漏れの経路がないか確認する