Pythonよくあるエラー一覧と解決方法
初心者がよく遭遇する22種類のエラーを、原因・エラーメッセージ・解決方法とともに丁寧に解説します。表示された英語メッセージをそのままコピペして探せる逆引き表から始めれば、自分のエラーの解説に最短でたどり着けます。
エラーが起きたら、まず最終行のエラーメッセージを確認しましょう。File "〜.py", line XX でエラーが起きた行番号がわかります。エラーの種類(TypeError: など)と説明文を組み合わせると原因を特定できます。表示された英語をそのまま探したい方は逆引き表へ、読み方から知りたい方はトレースバックの読み方へどうぞ。書き方そのものが合っているか確かめたいときは、Python構文チートシート83項目で正しい書き方を確認してください。
公式の解説もあわせてどうぞ:Python公式チュートリアル「エラーと例外」
エラーメッセージ逆引き表(英語メッセージから探す)
Python のエラーは末尾に英語のメッセージが表示されます。その英文をそのまま下の表から探すと、原因と詳しい解説に最短でたどり着けます。表示されたメッセージ(NameError: の後ろなど)と見比べてください。'x' のようにクォートで囲まれた部分はあなたの変数名やファイル名が入る箇所なので、そこは読み替えて照合します。
| 表示される英語メッセージ(一部) | エラーの種類 | かんたんな意味 | 解説 |
|---|---|---|---|
invalid syntax | SyntaxError | コロン・括弧・クォートの書き忘れなど文法ミス(構文エラー) | §1へ |
expected ':' | SyntaxError | if・for・def の行末のコロンが無い | §1へ |
'(' was never closed / '[' was never closed | SyntaxError | 括弧が開いたまま閉じられていない | §1へ |
incomplete input | SyntaxError | Jupyter・Colab などのセル実行で、入力が途中で終わっている(同じコードをファイルとして実行すると '(' was never closed などに変わる) | §1-3へ |
unexpected EOF while parsing / unterminated string literal | SyntaxError | 括弧やクォートが閉じられないまま行末・ファイル末尾に達した | §1へ |
invalid non-printable character U+3000 | SyntaxError | 全角スペースが紛れ込んでいる(日本語環境で頻出) | §1へ |
Missing parentheses in call to 'print' | SyntaxError | Python 2 の書き方 print "x" のまま書いている | §1へ |
expected an indented block | IndentationError | 字下げが必要な行がインデントされていない | §2へ |
unexpected indent | IndentationError | 不要な字下げが入っている | §2へ |
inconsistent use of tabs and spaces | TabError | タブとスペースが混在している | §2へ |
name 'x' is not defined | NameError | 未定義の変数/スペルミス | §3へ |
can only concatenate str (not "int") to str | TypeError | 文字列と数値を + で結合した | §4へ |
'float' object cannot be interpreted as an integer | TypeError | 整数が必要な所に小数を渡した(range() 等) | §4へ |
'NoneType' object cannot be interpreted as an integer | TypeError | 整数が必要な所に None を渡した(値を返さない関数の戻り値など) | §4へ |
'str' object cannot be interpreted as an integer | TypeError | 整数が必要な所に文字列を渡した(input() の結果をそのまま使った等) | §4へ |
unsupported operand type(s) for ... | TypeError | 型が合わない同士で計算した | §4へ |
'X' object is not callable | TypeError | 関数でないもの(変数・数値など)を () で呼び出した/関数名を変数で上書きした | §4へ |
'X' object is not subscriptable | TypeError | [ ] で添字アクセスできない型(数値・関数など)に添字を付けた | §4へ |
'NoneType' object is not iterable | TypeError | None(戻り値がない関数の結果など)を for やアンパックで回そうとした | §4へ |
unhashable type: 'list' | TypeError | リストなど変更可能な値を辞書のキーや set の要素にした | §4へ |
takes N positional arguments but M were given | TypeError | 関数に渡した引数の個数が合わない(self の付け忘れも該当) | §4へ |
sort() takes no positional arguments | TypeError | list.sort() に引数を位置指定で渡した(key= や reverse= のキーワード指定が必要) | §4へ |
invalid literal for int() with base 10 | ValueError | 数値にできない文字列を int() に渡した | §5へ |
math domain error | ValueError | math.sqrt(-1) のように、数学的に定義できない値を math の関数に渡した | §5へ |
list index out of range | IndexError | リストの範囲外を参照した | §6へ |
string index out of range | IndexError | 文字列の範囲外を参照した | §6へ |
list assignment index out of range | IndexError | まだ存在しない位置に lst[5] = x のように代入した | §6へ |
KeyError: 'x' | KeyError | 辞書に存在しないキーを参照した | §7へ |
'X' object has no attribute 'Y' | AttributeError | メソッド名のスペルミス/型違い | §8へ |
'NoneType' object has no attribute ... | AttributeError | None に対してメソッドを呼んだ | §8へ |
No module named 'x' | ModuleNotFoundError | 未インストール/スペルミス/仮想環境 | §9へ |
cannot import name 'X' from 'Y' | ImportError | モジュールはあるが、その中に指定した名前がない/循環インポート | §21へ |
cannot import name 'X' from partially initialized module(circular import) | ImportError | 2つのファイルが互いに import し合う循環インポート | §21へ |
No such file or directory | FileNotFoundError | ファイルパスが間違っている | §10へ |
division by zero | ZeroDivisionError | ゼロで割った | §11へ |
maximum recursion depth exceeded | RecursionError | 再帰の終了条件がなく無限に呼び出した | §12へ |
'utf-8' codec can't decode byte ... | UnicodeDecodeError | 文字コードの指定が実ファイルと不一致 | §13へ |
'cp932' codec can't decode byte ... | UnicodeDecodeError | UTF-8で保存されたファイルをcp932(Shift-JIS)として読んで失敗(Windowsでは encoding を省略すると既定がcp932になる) | §13へ |
Permission denied | PermissionError | 権限不足/別アプリがファイルを使用中 | §14へ |
cannot access local variable 'x' where it is not associated with a value(3.10以前は local variable 'x' referenced before assignment) | UnboundLocalError | 関数内で global 宣言を忘れた | §15へ |
math range error | OverflowError | 浮動小数点が表現できる上限を超えた | §17へ |
main thread is not in main loop | RuntimeError | tkinter を別スレッドから直接操作した | §19へ |
StopIteration | StopIteration | next() でイテレータの終端を越えて進めた | §16へ |
MemoryError | MemoryError | 巨大データを一度に読み込みメモリを使い果たした | §18へ |
AssertionError | AssertionError | assert 文の条件が False になった | §20へ |
KeyboardInterrupt | KeyboardInterrupt | 実行中に Ctrl + C を押した/無限ループを手動で止めた | §22へ |
このページ内で Ctrl + F(Mac は ⌘ + F)を押し、英語メッセージの一部を貼り付けて検索すると、該当箇所がすぐ見つかります。下の目次から種類別に探すこともできます。
なお、エラーメッセージの文面は Python のバージョンで変わることがあります。たとえば括弧の閉じ忘れは、3.9 以前が unexpected EOF while parsing、3.10 以降は '(' was never closed のように、より具体的な表現に改善されています。Python 3.10 以降では NameError: name 'prnt' is not defined. Did you mean: 'print'? のように正しい候補まで提示されるので、まずその候補を試すのが最短です。ただしこの候補表示は、Jupyter・Colab(IPython)のように独自のエラー表示を使う環境では出ないことがあります(本ページの検証環境は Python 3.12.10 / Windows)。
エラーメッセージ(トレースバック)の読み方
Python のエラー表示は Traceback(トレースバック) と呼ばれます。何行も英語が並ぶので身構えてしまいますが、読む順番を決めてしまえば数秒で原因の場所にたどり着けます。ポイントはひとつ、上からではなく下から読むことです。
実際に落としたコードで確かめる
説明だけでは分かりにくいので、実際にエラーを起こしてみます。次の2つのファイルを同じフォルダに置いてください。
def calc_average(values):
return sum(values) / len(values)
from utils import calc_average
scores = [] # 空のリストを渡してしまった
print(calc_average(scores))
main.py を実行すると、次のトレースバックが表示されます。
Traceback (most recent call last):
File "C:\python\main.py", line 4, in <module>
print(calc_average(scores))
^^^^^^^^^^^^^^^^^^^^
File "C:\python\utils.py", line 2, in calc_average
return sum(values) / len(values)
~~~~~~~~~~~~^~~~~~~~~~~~~
ZeroDivisionError: division by zero
Python 3.12.10(Windows)で実際に実行した出力です。ファイルパスの部分だけ C:\python\ と短く書き換えています(実際にはお使いのフォルダのフルパスが表示されます)。行番号・記号・メッセージは実行結果そのままです。
読む順番は ①最終行 → ②発生行 → ③呼び出し経路
-
1
一番下の行を読む(エラーの種類と内容)
この例では
ZeroDivisionError: division by zero。コロンの左がエラーの種類、右が内容です。この英文を逆引き表で探せば、原因と直し方の解説にすぐ飛べます。 -
2
下から2つ目の
File行を見る(実際に落ちた場所)File "C:\python\utils.py", line 2, in calc_averageなので、utils.pyの2行目、calc_average関数の中で落ちています。すぐ下にその行のコードが再掲されるので、エディタで開かなくても内容が確認できます。 -
3
File行の並びを上から下へ見る(呼び出し経路)File行は呼び出した順に並びます。この例は「main.pyの4行目がcalc_average()を呼び、その中で落ちた」という経路です。本当の原因は上のほうにあることが多いのがポイントで、ここではutils.pyではなく、空のリストを渡したmain.pyの3行目を直すべきだと分かります。
「^^^^」「~~~~^~~~~」の記号が指しているもの
コード行の下に付く記号は、その行のどの部分でエラーが起きたかを文字単位で示すマーカーです。1行に複数の処理が並んでいても、犯人をピンポイントで特定できます。
| 記号 | 意味 |
|---|---|
^^^^ | エラーが起きた式そのものの範囲。例では calc_average(scores) の呼び出し全体 |
~~~~^~~~~ | ~ が演算の左右のオペランド、^ がその演算子。例では sum(values) / len(values) の / が原因だと示している |
この位置マーカーは Python 3.11 で追加された機能です(PEP 657)。3.10 以前では表示されないので、記号が出ない環境ではエラー行のコードを自分で読む必要があります。バージョンは python --version で確認できます。導入や更新の手順はPythonのインストールにまとめています。
自分が書いていないファイルが出てきたときは
pandas や requests などのライブラリを使っていると、トレースバックに site-packages 配下の見覚えのないファイルが並ぶことがあります。そんなときは下から順に見ていき、自分のファイル名が最初に出てくる File 行を探してください。そこが「自分のコードがライブラリを呼んだ場所」で、多くの場合は渡した値が原因です。ライブラリの中身を読む必要はほとんどありません。
英語のメッセージは翻訳せず、そのまま検索する
エラーメッセージを日本語に訳してから検索すると、情報量が一気に減ります。英語のまま検索するのが基本です。検索するときは次の2点を意識すると精度が上がります。
- 自分固有の部分を消す:
No module named 'pandas_myapp'のようにクォート内は自分の環境の名前なので、検索ではNo module namedのように共通部分だけを使うか、一般的なライブラリ名に置き換えます - 先頭に
pythonを付ける:python list index out of rangeのようにすると、他言語の同名エラーが混ざりません
公式の説明を直接読みたいときは、Python公式ドキュメント「組み込み例外」にすべての例外の定義がまとまっています。
- 📖 エラーの読み方・基礎
- 🔤 文法・インデント系
- 🏷️ 名前・型・値系
- 🗂️ リスト・辞書系
- 📦 インポート・ファイル系
- ⚙️ 実行時・その他
1. SyntaxError(構文エラー)
日本語で構文エラーと呼ばれるエラーです。Pythonの文法規則に違反したコードを書いたときに発生します。プログラムの実行前にチェックされるため、1行でも構文エラーがあると、そのファイルは1行も実行されません。「print の結果すら表示されない」と感じたら、まずこのエラーを疑ってください。
SyntaxError のよくある原因(コロン・括弧・全角文字)
- コロン(
:)の書き忘れ(if・for・defの行末) - 括弧・クォートの閉じ忘れ
- 全角スペースや全角文字の混入
if x > 0 # コロンがない
print("正の数")
for i in range(5) # コロンがない
print(i)
print("Hello" # 括弧が閉じていない
if x > 0: # コロンを追加
print("正の数")
for i in range(5): # コロンを追加
print(i)
print("Hello") # 括弧を閉じる
日本語環境では全角スペース( )が混入することがあります。エラー行に見た目上の問題がない場合は、全角文字が混入していないか確認しましょう。VSCodeなら全角スペースが可視化されます。実際に print(x) の行頭へ全角スペースを1つ入れて実行すると、SyntaxError: invalid non-printable character U+3000 と表示されます(U+3000 が全角スペースの文字コードです)。全角の丸括弧を使った場合は SyntaxError: invalid character '(' (U+FF08) になります。
構文エラーのメッセージ別・直し方早見表
SyntaxError はメッセージを見れば原因がほぼ絞れます。以下はすべて Python 3.12.10 で実際に実行して確認した表示です。表示された英文と見比べてください。
| 表示されるメッセージ | 原因 | 直し方 |
|---|---|---|
expected ':' | if・for・def・class の行末にコロンが無い | 行末に : を付ける |
'(' was never closed | 開いた括弧が閉じられていない | 指し示された括弧に対応する ) を補う。[ や { でも同じ形式で表示される |
unterminated string literal (detected at line N) | クォートが閉じられていない | 行末に閉じクォートを補う。三重クォートの場合は unterminated triple-quoted string literal と表示される |
invalid syntax. Maybe you meant '==' or ':=' instead of '='? | if x = 1: のように、比較すべき場所で代入している | 比較は == に直す |
invalid syntax. Perhaps you forgot a comma? | リストや引数の区切りのカンマが抜けている | 指摘された位置に , を補う |
Missing parentheses in call to 'print'. Did you mean print(...)? | Python 2 の書き方 print "x" のまま書いている | print("x") と括弧を付ける |
invalid non-printable character U+3000 | 全角スペースが紛れ込んでいる | 該当位置の全角スペースを半角に置き換える |
invalid character '(' (U+FF08) | 全角の括弧・クォートなどを使っている | 半角記号に直す。日本語入力のオン・オフの切り替え忘れが原因 |
invalid decimal literal | 12abc のように数字で始まる不正な名前・数値を書いた | 変数名は数字で始められない。abc12 のように直す |
cannot assign to literal here. Maybe you meant '==' instead of '='? | 5 = x のように左辺と右辺が逆になっている | 代入は x = 5 の向きに直す |
'return' outside function | return を関数の外に書いた(インデント漏れも該当) | def の中に入れる。インデントを確認する |
「SyntaxError: incomplete input」と表示されたら(Jupyter・Colab で出る)
SyntaxError: incomplete input は、Pythonが「コードがまだ途中で終わっている」と判断したときに出る構文エラーです。特徴的なのは出る場所が限られていることで、手元の Python 3.12.10 と IPython 9.16.1 で試したところ、次の結果になりました。
| 実行のしかた | print("hello" を実行した結果 |
|---|---|
| Jupyter Notebook・Google Colab・IPython のセル | SyntaxError: incomplete input |
python main.py でファイルとして実行 | SyntaxError: '(' was never closed |
ターミナルの対話モード(>>>) | 入力途中とみなされ ... の継続プロンプトになる |
つまり incomplete input を見ているなら、ほぼ確実に Jupyter・Colab 系のセル実行環境です(これらは内部で IPython を使っています)。原因はほぼ閉じ忘れで、次の4パターンがいずれも incomplete input になることを確認しました。
print("hello" # 丸括弧を閉じていない
x = [1, 2, # 角括弧を閉じていない
x = """abc # 三重クォートを閉じていない
if True: # コロンの後に中身を書いていない
- そのセル・その入力の最後の行から上へ、
([{と"'の数が合っているか確認する ifやfor、defでコロンまで書いて中身が空なら、中身を書くか仮にpassを置く- セル全体をコピーして
.pyファイルに貼り、python ファイル名.pyで実行し直す
3 の方法が有効なのは、ファイルとして実行するとより具体的なメッセージに変わるからです。同じ print("hello" でも、ファイル実行なら SyntaxError: '(' was never closed と表示され、どの括弧が原因かまで教えてくれます。原因が分からないときの回り道として覚えておくと便利です。
ノートブックのセルは1つずつ実行されるため、複数行にまたがる処理を途中でセル分割してしまうと incomplete input になります。関数定義やループは、def から中身まで同じセルに収めてください。
コロンやクォート、括弧のルールがあいまいだとSyntaxErrorは繰り返し起こります。Pythonの基本構文で if・for・def の書き方を一度整理しておくと、根本から減らせます。書き方をその場で確認したいときは基本構文チートシート83項目が早いです。
2. IndentationError(インデントエラー)
日本語でインデントエラー(字下げのエラー)と呼ばれます。Pythonはインデント(字下げ)でコードブロックの範囲を表現するため、他の言語なら見た目の問題で済むズレが、そのままエラーになります。SyntaxError(構文エラー)の一種で、これも実行前に検出されます。
インデントエラー(IndentationError)のよくある原因(タブとスペースの混在)
- スペースとタブを混在させている
- インデントの深さが揃っていない
- インデントが必要な箇所でされていない
def greet(name):
print("Hello")
print(name) # インデントの深さが違う
if True:
print("OK") # インデントがない(expected an indented block)
def greet(name):
print("Hello")
print(name) # 同じ深さに揃える(スペース4つ)
if True:
print("OK") # ifブロック内は1段階深くインデント
Pythonの慣習ではスペース4つでインデントします。VSCodeでは「インデントをスペースに変換」設定でタブをスペースに統一できます。エディタの設定で「タブをスペースで表示」をオンにすると混在を防げます。
インデントエラー(IndentationError)のメッセージ別・原因早見表
IndentationError はメッセージで原因がほぼ特定できます。表示された英文と見比べてください。
| エラーメッセージ | 意味 | 直し方 |
|---|---|---|
expected an indented block | インデントすべき行(if・for・def の直後など)が字下げされていない | ブロックの中身を1段階(スペース4つ)下げる。中身を後で書くなら仮に pass を置く |
unexpected indent | インデント不要な行が字下げされている | 行頭の余分なスペースを削除する。コピペ直後によく起きる |
unindent does not match any outer indentation level | インデントの深さがどの階層とも一致しない(タブとスペースの混在が典型) | 該当行を一度行頭まで消して、スペースだけで揃え直す |
inconsistent use of tabs and spaces(TabError) | 同じブロック内でタブとスペースが混在 | 下記のVSCode手順でファイル全体をスペースに統一する |
VSCodeで混在を一括解消する手順
- 右下ステータスバーの「スペース: 4」(または「タブのサイズ」)表示をクリック
- 「インデントをスペースに変換」を選択 → ファイル全体のタブがスペースに置き換わる
- 再発防止に、設定(
Ctrl+,)で「Editor: Insert Spaces」をオン、「Editor: Render Whitespace」をallにすると空白が可視化されて混在に気づけます
それでも解決しない場合は、エラー行だけでなくその1つ上の行のインデントも確認してください。原因がエラー表示行の手前にあることがよくあります。空白の可視化やタブ→スペース変換の設定はVSCodeのセットアップのページにまとめています。
3. NameError(名前エラー)
定義されていない変数・関数・クラスを使おうとしたときに発生します。
NameError のよくある原因(スペルミス・定義前の参照)
- 変数名のスペルミス(
countをcoutnと書くなど) - 変数を代入する前に参照している
- スコープ外の変数を参照している
print(message) # まだ定義していない
# NameError: name 'message' is not defined
total = coutn + 1 # スペルミス
# NameError: name 'coutn' is not defined
message = "Hello" # 使う前に定義する
print(message)
count = 0
total = count + 1 # 正しいスペルで
4. TypeError(型エラー)
異なる型同士の演算や、関数への引数の型が合わないときに発生します。
TypeError のよくある原因(文字列と数値の連結・引数の数)
- 文字列と数値を
+で結合しようとした - 整数型に対して文字列向けのメソッドを呼んだ
- 関数の引数の数が合わない
age = 25
print("年齢は" + age + "歳です")
# TypeError: can only concatenate str (not "int") to str
def add(a, b):
return a + b
add(1, 2, 3)
# TypeError: add() takes 2 positional arguments but 3 were given
age = 25
# 方法1: str()で変換
print("年齢は" + str(age) + "歳です")
# 方法2: f-string(推奨)
print(f"年齢は{age}歳です")
def add(a, b):
return a + b
add(1, 2) # 引数の数を合わせる
| エラーメッセージ | よくある原因 | 直し方 |
|---|---|---|
'X' object is not callable | 関数でないもの(変数・数値・リスト)を () で呼び出した。関数名と同じ名前の変数で上書きしているケースが多い | 同名の変数で関数を潰していないか確認(例: list = [1,2] の後に list(...) は不可) |
'X' object is not subscriptable | 角括弧 [] で添字アクセスできない型(関数・数値・None)に x[0] した | 対象が本当にリスト/辞書/文字列か確認。関数なら () の付け忘れを疑う |
'NoneType' object is not iterable | None を for やアンパックで回した。値を return しない関数の戻り値を使っていることが多い | 関数がちゃんと値を返しているか、変数が None でないか確認 |
unhashable type: 'list' | リストや辞書を、辞書のキーや set の要素に使った(変更可能な型はハッシュ化できない) | キーには (1, 2) のようなタプル(変更不可の型)を使う |
'NoneType' object cannot be interpreted as an integer | 整数が必要な場所に None を渡した。range(n) の n が、値を return し忘れた関数の戻り値になっているケースが典型 | 渡す直前に print(n, type(n)) で確認し、関数が値を返しているかを見る |
'str' object cannot be interpreted as an integer | 整数が必要な場所に文字列を渡した。input() の戻り値をそのまま range() に入れた場合が典型(input() は常に文字列を返す) | range(int(input())) のように int() で変換する |
'float' object cannot be interpreted as an integer | 整数が必要な場所に小数を渡した(range(2.5) など) | int(2.5) で整数に変換する。割り算の結果を使うなら / ではなく // を使う |
sort() takes no positional arguments | list.sort() に引数を位置指定で渡した([3,1,2].sort(True) など)。sort() はキーワード引数しか受け取らない | sort(reverse=True)・sort(key=len) のように 名前=値 の形で渡す |
5. ValueError(値エラー)
型は正しいが、値が無効なときに発生します。文字列を整数に変換しようとして失敗するケースが最多です。
ValueError のよくある原因(int() への変換失敗・アンパック)
- 数字以外の文字列を
int()やfloat()に渡した - リストに存在しない値を
remove()した unpack時の要素数が合わない
num = int("abc")
# ValueError: invalid literal for int() with base 10: 'abc'
num = int("3.14")
# ValueError: invalid literal for int() with base 10: '3.14'
a, b = [1, 2, 3]
# ValueError: too many values to unpack (expected 2)
# 変換前にチェックするか、try-except で対処
text = "abc"
try:
num = int(text)
except ValueError:
print(f"'{text}' は整数に変換できません")
# 小数点を含む文字列はfloat()で変換
num = float("3.14") # 3.14
num_int = int(float("3.14")) # 3
# アンパックの要素数を合わせる
a, b, c = [1, 2, 3]
# または
a, *rest = [1, 2, 3] # a=1, rest=[2,3]
ValueError: math domain error も ValueError の仲間です。math.sqrt(-1) や math.log(0) のように、数学的に答えが定義できない値を math の関数に渡したときの表示で、Python 3.12.10 でどちらも同じメッセージになることを確認しています。負の数やゼロを渡していないか、渡す直前に print(x) で値を確かめてください。負数の平方根を扱いたい場合は cmath.sqrt(-1) を使うと複素数として計算できます。
入力欄やCSVから受け取った文字列を float() に渡す場合は、読めない文字列より「読めてしまう値」のほうが厄介です。全角数字・"0"・負の数・"nan"・"inf" はいずれも ValueError にならずに通り、変換に成功したあとで計算のほうが壊れます(一方で全角の小数点「.」は弾かれます)。Python 3.12.10 で15パターンを実際に通した一覧はBMI計算アプリの「float() が通すもの・弾くもの」で確認できます。
6. IndexError(インデックスエラー)
リストや文字列の存在しないインデックスにアクセスしたときに発生します。
IndexError のよくある原因(0始まりの添字・空リスト)
- 要素数と同じインデックスを指定した(0始まりなので最大は
len()-1) - 空リストの要素にアクセスした
- ループ内でインデックス計算を間違えた
items = ["apple", "banana", "cherry"]
print(items[3]) # インデックス3は存在しない(0〜2)
# IndexError: list index out of range
empty = []
print(empty[0]) # 空リスト
# IndexError: list index out of range
items = ["apple", "banana", "cherry"]
# インデックスの範囲を確認してからアクセス
i = 3
if i < len(items):
print(items[i])
else:
print("インデックスが範囲外です")
# 最後の要素は -1 で取得できる
print(items[-1]) # "cherry"
# 空リストチェック
if items:
print(items[0])
「list assignment index out of range」と表示されたら
読み取りではなく代入で範囲外を指定すると、メッセージが list assignment index out of range(リストへの代入が範囲外)に変わります。「まだ存在しない場所に値を入れようとした」という意味で、リストは代入だけでは自動的に伸びません。
scores = []
scores[0] = 80 # 空のリストの0番目はまだ存在しない
# IndexError: list assignment index out of range
nums = [1, 2, 3]
nums[5] = 10 # 5番目もまだ存在しない
# IndexError: list assignment index out of range
scores = []
scores.append(80) # 末尾に追加するなら append()
print(scores) # [80]
# 決まった長さで先に確保しておく方法
nums = [0] * 6 # 0〜5番目まで用意される
nums[5] = 10
print(nums) # [0, 0, 0, 0, 0, 10]
# 内包表記でまとめて作る方法
squares = [i * i for i in range(6)]
print(squares) # [0, 1, 4, 9, 16, 25]
ループの中で result[i] = ... と書きたくなったら、多くの場合は result.append(...) か内包表記で書き直せます。基本構文チートシートのリスト操作の項目もあわせてどうぞ。
GUIアプリでは、同じ IndexError が tuple index out of range という形で出ることがあります。典型は tkinter の Listbox で何も選ばれていないのに listbox.curselection()[0] を読むケースで、選択が無いときの戻り値は空のタプルなので0番目が存在しません。画面には何も出ずターミナルにだけエラーが表示されるため、ボタンが無反応に見えるのが厄介です。再現手順と回避の書き方はToDoリストアプリで選択が空のまま削除したときの症状別チェックで確認できます。
7. KeyError(キーエラー)
辞書に存在しないキーにアクセスしたときに発生します。
KeyError のよくある原因(キーのスペルミス・大文字小文字)
- キー名のスペルミス
- 存在するか確認せずに直接アクセス
- 大文字・小文字を間違えた(辞書のキーは大文字小文字を区別する)
person = {"name": "Alice", "age": 25}
print(person["email"])
# KeyError: 'email'
print(person["Name"]) # 大文字小文字が違う
# KeyError: 'Name'
person = {"name": "Alice", "age": 25}
# 方法1: get()を使う(キーがなければNoneまたはデフォルト値)
print(person.get("email")) # None
print(person.get("email", "未設定")) # "未設定"
# 方法2: inでキーの存在を確認
if "email" in person:
print(person["email"])
else:
print("emailキーが存在しません")
# 方法3: try-except
try:
print(person["email"])
except KeyError as e:
print(f"キーが見つかりません: {e}")
8. AttributeError(属性エラー)
オブジェクトに存在しない属性やメソッドを呼び出したときに発生します。
AttributeError のよくある原因(メソッド名のスペルミス・None)
- メソッド名のスペルミス(
appendをappnedなど) - 型を間違えた(リストに文字列のメソッドを使うなど)
Noneに対してメソッドを呼んだ
nums = [3, 1, 2]
nums.shorting() # shorting ではなく sort
# AttributeError: 'list' object has no attribute 'shorting'
result = None
result.append(1) # None は append メソッドを持たない
# AttributeError: 'NoneType' object has no attribute 'append'
text = "hello"
text.append("!") # 文字列はappendを持たない
# AttributeError: 'str' object has no attribute 'append'
nums = [3, 1, 2]
nums.sort() # 正しいメソッド名
# Noneチェックをしてからメソッドを呼ぶ
result = [] # 初期値をリストにする
result.append(1)
# 文字列への追加は + か join を使う
text = "hello"
text = text + "!"
# または
text = "".join(["hello", "!"])
# どんなメソッドがあるか確認する方法
print(dir([])) # リストのメソッド一覧
print(dir("")) # 文字列のメソッド一覧
9. ModuleNotFoundError(モジュール未発見エラー)
インポートしようとしたモジュールが見つからないときに発生します。ImportError の一種です。
ModuleNotFoundError のよくある原因(未インストール・仮想環境)
- モジュールを
pip installしていない - モジュール名のスペルミス
- 仮想環境が有効化されていない
import requests # インストールされていない場合
# ModuleNotFoundError: No module named 'requests'
import numppy # スペルミス
# ModuleNotFoundError: No module named 'numppy'
# ターミナルで pip install を実行する
# pip install requests
# pip install numpy pandas matplotlib
# インストール後に正しいスペルでインポート
import requests
import numpy as np
# インストール済みパッケージの確認
# pip list
# インポートできるか事前チェック(スクリプト内で)
try:
import requests
except ModuleNotFoundError:
print("requestsがインストールされていません")
print("pip install requests を実行してください")
os・sys・math・json・datetime などはPythonに最初から含まれています。それ以外のライブラリ(requests・numpy・pandasなど)は pip install が必要です。ただし tkinter は例外で、公式ドキュメントでは「オプションのモジュール」とされています。python.org の公式インストーラーではTcl/Tkが既定で同梱されますが、Linux系など配布元によっては別パッケージのため、No module named 'tkinter' になることがあります(この場合 pip install tkinter では解決しません)。配布元ごとの対処はtkinterでウィンドウを表示する方法(tkinterが使えるか確認する手順と対処表)にまとめています。
どのライブラリをどのコマンドで入れるかは主要ライブラリ一覧(pipインストール早見表)にまとめています。pip 自体が見つからない・python コマンドが動かないときは、まずPythonのインストールで環境を確認してください。
10. FileNotFoundError(ファイル未発見エラー)
指定したパスにファイルが存在しないときに発生します。
FileNotFoundError のよくある原因(パスの誤り・カレントディレクトリ)
- ファイルパスの書き間違い
- カレントディレクトリが想定と異なる
- ファイル名の大文字小文字が違う(特にLinux/Mac)
with open("data.txt", "r") as f:
content = f.read()
# FileNotFoundError: [Errno 2] No such file or directory: 'data.txt'
with open("C:/Users/hoge/myfile.txt", "r") as f:
content = f.read()
# パスが間違っていてもFileNotFoundError
import os
from pathlib import Path
# 現在のディレクトリを確認
print(os.getcwd())
# ファイルの存在確認
path = Path("data.txt")
if path.exists():
with open(path, "r", encoding="utf-8") as f:
content = f.read()
else:
print(f"ファイルが見つかりません: {path.resolve()}")
# try-exceptで安全に開く
try:
with open("data.txt", "r", encoding="utf-8") as f:
content = f.read()
except FileNotFoundError as e:
print(f"エラー: {e}")
# スクリプトと同じフォルダのファイルを確実に開く
script_dir = Path(__file__).parent
data_path = script_dir / "data.txt"
11. ZeroDivisionError(ゼロ除算エラー)
数値をゼロで割ろうとしたときに発生します。
result = 10 / 0
# ZeroDivisionError: division by zero
result = 10 // 0
# ZeroDivisionError: integer division or modulo by zero
result = 10 % 0
# ZeroDivisionError: integer modulo by zero
# 方法1: 事前にゼロチェック
def safe_divide(a, b):
if b == 0:
return None # またはデフォルト値
return a / b
print(safe_divide(10, 2)) # 5.0
print(safe_divide(10, 0)) # None
# 方法2: try-except
a, b = 10, 0 # b が 0 のときを想定
try:
result = a / b
except ZeroDivisionError:
result = 0
print("0では割れません")
print(result) # 0
入力欄から受け取った値では、捕まえるより「割る前に止める」ほうが親切なメッセージを出せます。float("0") は成功してしまうので except ValueError では拾えず、割り算の瞬間に上の3つとは別の float division by zero になります。< 0 ではなく <= 0 で弾く理由と、GUIでの止め方はBMI計算アプリのZeroDivisionError対処に実測つきでまとめています。
12. RecursionError(再帰エラー)
再帰関数が深すぎて、Pythonの再帰上限(デフォルト1000回)に達したときに発生します。
RecursionError のよくある原因(終了条件の不備・無限再帰)
- 再帰の終了条件(ベースケース)が間違っている
- 終了条件に到達しない無限再帰
def countdown(n):
print(n)
countdown(n - 1) # 終了条件がない無限再帰
countdown(5)
# RecursionError: maximum recursion depth exceeded
# 終了条件(ベースケース)を必ず書く
def countdown(n):
if n <= 0: # ベースケース
print("終了")
return
print(n)
countdown(n - 1)
countdown(5) # 5, 4, 3, 2, 1, 終了
# 再帰が深くなる処理はループに書き換えることも検討
def countdown_loop(n):
while n > 0:
print(n)
n -= 1
print("終了")
# 再帰の上限を変更する場合(慎重に)
import sys
sys.setrecursionlimit(5000)
13. UnicodeDecodeError(文字コードエラー)
ファイルを読み込む際、指定した文字コードと実際のファイルの文字コードが一致しないときに発生します。Windows環境でよく起こります。
UnicodeDecodeError のよくある原因(cp932 と UTF-8 の食い違い)
- Windowsで作成したCSV/テキストファイルは
cp932(Shift-JIS)の場合がある encodingを指定しないと環境依存のデフォルト設定が使われる
with open("japanese.txt", "r", encoding="utf-8") as f:
content = f.read()
# UnicodeDecodeError: 'utf-8' codec can't decode byte ...
# (ファイルがShift-JISで保存されている場合)
# Shift-JIS(cp932)で開く
with open("japanese.txt", "r", encoding="cp932") as f:
content = f.read()
# 文字コードが不明な場合は errors='replace' か 'ignore'
with open("japanese.txt", "r", encoding="utf-8", errors="replace") as f:
content = f.read()
# chardetで文字コードを自動検出(pip install chardet が必要)
import chardet
with open("japanese.txt", "rb") as f:
raw = f.read()
detected = chardet.detect(raw)
encoding = detected["encoding"]
print(f"検出された文字コード: {encoding}")
content = raw.decode(encoding)
14. PermissionError(権限エラー)
ファイルやディレクトリへのアクセス権限がないときに発生します。
PermissionError のよくある原因(別アプリが使用中・読み取り専用)
- 他のアプリケーションが同じファイルを開いている(Excelで開いているCSVなど)
- 読み取り専用ファイルへの書き込み
- システムフォルダや保護されたパスへのアクセス
with open("data.csv", "w") as f: # Excelで開いている場合
f.write("name,age\n")
# PermissionError: [Errno 13] Permission denied: 'data.csv'
import os
# 1. 他のアプリでファイルが開いていないか確認してから実行
# 2. try-exceptで対処
try:
with open("data.csv", "w", encoding="utf-8") as f:
f.write("name,age\n")
except PermissionError:
print("ファイルが他のプログラムで使用中か、権限がありません")
print("Excelなど開いているアプリを閉じてから再実行してください")
# 3. 書き込み先を変更する
output_path = os.path.join(os.path.expanduser("~"), "output.csv")
with open(output_path, "w", encoding="utf-8") as f:
f.write("name,age\n")
15. UnboundLocalError(未束縛ローカル変数エラー)
関数内でグローバル変数と同名のローカル変数を代入しようとしたが、代入前に参照してしまったときに発生します。
count = 0
def increment():
print(count) # ここでエラー
count += 1 # 代入があるので count はローカル変数とみなされる
increment()
# Python 3.11 以降:
# UnboundLocalError: cannot access local variable 'count'
# where it is not associated with a value
# Python 3.10 以前:
# UnboundLocalError: local variable 'count' referenced before assignment
count = 0
# 方法1: global宣言を使う
def increment():
global count
print(count)
count += 1
increment() # 0
increment() # 1
# 方法2: 引数と戻り値を使う(より良い設計)
def increment(count):
return count + 1
count = 0 # 方法2はあらためて0から試す
count = increment(count) # count = 1
count = increment(count) # count = 2
# 方法3: クラスを使って状態を管理する
class Counter:
def __init__(self):
self.count = 0
def increment(self):
self.count += 1
このエラーは変数の「スコープ(有効範囲)」を理解すると避けやすくなります。関数の使い方で引数・戻り値・ローカル変数とグローバル変数の違いを整理しておくのがおすすめです。
16. StopIteration(イテレータ終端エラー)
next() でイテレータを手動で進めようとしたが、要素がなくなったときに発生します。
items = iter([1, 2])
print(next(items)) # 1
print(next(items)) # 2
print(next(items)) # StopIteration(要素がない)
items = iter([1, 2])
# 方法1: next()のデフォルト値を指定
print(next(items, None)) # 1
print(next(items, None)) # 2
print(next(items, None)) # None(エラーにならない)
# 方法2: try-except
items = iter([1, 2])
while True:
try:
item = next(items)
print(item)
except StopIteration:
break
# 方法3: 普通のforループ(最も推奨)
for item in [1, 2]:
print(item)
17. OverflowError(オーバーフローエラー)
浮動小数点数が表現できる最大値を超えたときに発生します。なお、Python の整数型(int)は任意精度なのでオーバーフローしません。
import math
result = math.exp(1000) # e^1000 は float で表現できない
# OverflowError: math range error
result = float(10 ** 400) # int→float変換でオーバーフロー
# OverflowError: int too large to convert to float
import math
from decimal import Decimal
# 対数スケールで計算する
log_result = 1000 * math.log(math.e) # log(e^1000) = 1000
# Decimal モジュールで高精度計算
result = Decimal(10) ** 400 # Decimal は任意精度
# try-except で対処
try:
result = math.exp(1000)
except OverflowError:
result = float("inf") # 無限大として扱う
18. MemoryError(メモリエラー)
プログラムがメモリを使い果たしたときに発生します。巨大なデータを一度にメモリに読み込もうとすると起こりやすいです。
# メモリを大量に使うコード例
huge_list = list(range(10 ** 9)) # 10億要素のリスト
# MemoryError
# 巨大ファイルを一括読み込み
with open("10gb_file.txt", "r") as f:
content = f.read() # 全内容をメモリに展開
# MemoryError
# 方法1: range やジェネレータを使う(メモリに全部展開しない)
huge_range = range(10 ** 9) # range は必要になるまで値を作らない(遅延シーケンス)
for i in huge_range:
if i > 100:
break
# 方法2: ファイルを1行ずつ読む
with open("large_file.txt", "r", encoding="utf-8") as f:
for line in f: # 1行ずつ処理
process(line.strip())
# 方法3: pandasのchunksize(大きなCSVを分割処理)
import pandas as pd
for chunk in pd.read_csv("large.csv", chunksize=10000):
process(chunk)
# 方法4: 不要なオブジェクトを明示的に解放
del huge_list
import gc
gc.collect()
コードを工夫してもメモリが足りない、あるいは大きなデータ処理で動作が極端に重い場合は、搭載メモリ(RAM)不足など環境要因のこともあります。目安のスペックはPython学習・開発向けPCの選び方を参考にしてください。
19. RuntimeError(ランタイムエラー)
実行時に様々な原因で発生する汎用エラーです。tkinter を使ったGUIアプリで「メインスレッド以外でGUIを操作した」際に特によく見られます。
RuntimeError のよくある原因(tkinter を別スレッドから操作)
- スレッド(
threading)の中から直接Labelの更新などを行った - GUIの初期化前にウィジェットを操作した
import tkinter as tk
import threading
root = tk.Tk()
label = tk.Label(root, text="待機中")
label.pack()
def update_label():
import time
time.sleep(2)
label.config(text="完了!") # スレッド内からGUIを直接更新
thread = threading.Thread(target=update_label)
thread.start()
root.mainloop()
# RuntimeError: main thread is not in main loop
import tkinter as tk
import threading
root = tk.Tk()
label = tk.Label(root, text="待機中")
label.pack()
def background_task():
import time
time.sleep(2)
# GUIの更新はafter()経由でメインスレッドに渡す
root.after(0, lambda: label.config(text="完了!"))
thread = threading.Thread(target=background_task, daemon=True)
thread.start()
root.mainloop()
20. AssertionError(アサーションエラー)
assert 文の条件が False になったときに発生します。デバッグや前提条件チェックに使われます。
def divide(a, b):
assert b != 0, "bはゼロ以外の値を指定してください"
return a / b
result = divide(10, 0)
# AssertionError: bはゼロ以外の値を指定してください
score = -5
assert 0 <= score <= 100, f"スコアが範囲外です: {score}"
# AssertionError: スコアが範囲外です: -5
# assertのエラーメッセージを読んで、条件を満たす値を渡す
result = divide(10, 2) # b != 0 を満たす値を渡す
score = 85
assert 0 <= score <= 100 # OK
# 本番コードではassertの代わりにValueErrorを使うのが推奨
def divide(a, b):
if b == 0:
raise ValueError("bはゼロ以外の値を指定してください")
return a / b
# assert は -O(最適化)フラグで無効化されることに注意
# python -O script.py → assertが全て無視される
21. ImportError(インポートエラー)
モジュール自体は見つかったものの、その中から指定した名前(関数・クラス・変数)を取り出せないときに発生します。「モジュールが丸ごと無い」場合の ModuleNotFoundError(§9) と混同しやすいので、メッセージで見分けます。
ImportError のよくある原因(名前のスペルミス・循環インポート)
- インポートする名前のスペルミス、またはそのバージョンに存在しない名前を指定した
- 2つのモジュールがお互いをインポートし合う「循環インポート」になっている
- 自分のファイル名を標準ライブラリと同じ名前(例:
random.py・json.py)にしてしまい、そちらが読み込まれた
from math import square_root # mathにこの名前は無い(正しくはsqrt)
# ImportError: cannot import name 'square_root' from 'math'
# 自作ファイルを random.py という名前で保存して実行した場合
import random
print(random.randint(1, 6))
# AttributeError や ImportError の原因になる
# (標準のrandomではなく自分のファイルが読み込まれるため)
# 正しい名前でインポートする
from math import sqrt
print(sqrt(16)) # 4.0
# そのモジュールに何があるか一覧で確認する
import math
print(dir(math)) # 使える関数名の一覧が見られる
# 自作ファイル名が標準ライブラリと被っていないか確認する
# random.py → my_random.py などにリネームし、
# 古いキャッシュ(__pycache__ フォルダ)が残っていれば削除する
メッセージに (most likely due to a circular import) と付く場合は、2つのファイルが互いを import し合っています。片方のインポートを関数の中に移す、共通部分を第3のファイルに分けるなどで解消できます。ライブラリのインストール状況を確認したいときは主要ライブラリ一覧もあわせてどうぞ。
22. KeyboardInterrupt(実行中断)
プログラムの実行中に Ctrl + C(Mac も Ctrl + C)を押して処理を止めたときに発生します。多くの場合はバグではなく、あなた自身が止めた合図です。ただし、意図せず無限ループに入ってしまい手動で止めたときにも出ます。
while True:
pass # 何も進まない無限ループ
# 実行中に Ctrl + C を押すと…
# Traceback (most recent call last):
# ...
# KeyboardInterrupt
# Ctrl + C を受け取って、後片付けをしてから終了する
try:
while True:
# 長時間動かす処理など
do_something()
except KeyboardInterrupt:
print("\n中断されました。終了します。")
# ここでファイルを閉じる・保存するなどの後始末を書く
# 無限ループが意図しないものなら、
# ループの終了条件(break や条件式)を見直す
count = 0
while count < 5:
print(count)
count += 1 # これを忘れると無限ループになる
裸の except:(=except BaseException:)は KeyboardInterrupt まで捕まえてしまい、Ctrl + C で止められなくなります。いっぽう except Exception: は KeyboardInterrupt を捕まえない(=Ctrl + C は効く)ので、まとめて例外を処理したいときは裸の except: は避けて except Exception: を使い、中断を自分で扱いたいときは except KeyboardInterrupt: と種類を明示しましょう。
例外の親子関係(例外階層)を知ると except が短くなる
ここまで22種類を個別に見てきましたが、Pythonの例外はばらばらに存在しているわけではなく、親子関係(クラスの継承関係)で整理されています。この関係を知っておくと、「似たエラーをまとめて捕まえる」「捕まえすぎを避ける」という書き分けができるようになります。
主要な例外の階層
Python公式ドキュメントの例外階層から、本ページで扱った22種類とその親クラスを抜き出したものです。
BaseException
├─ KeyboardInterrupt ← Ctrl + C
├─ SystemExit ← sys.exit()
├─ GeneratorExit
└─ Exception ← 通常のエラーはすべてこの下
├─ ArithmeticError
│ ├─ OverflowError
│ └─ ZeroDivisionError
├─ AssertionError
├─ AttributeError
├─ ImportError
│ └─ ModuleNotFoundError
├─ LookupError
│ ├─ IndexError
│ └─ KeyError
├─ MemoryError
├─ NameError
│ └─ UnboundLocalError
├─ OSError
│ ├─ FileNotFoundError
│ └─ PermissionError
├─ RuntimeError
│ └─ RecursionError
├─ StopIteration
├─ SyntaxError
│ └─ IndentationError
│ └─ TabError
├─ TypeError
└─ ValueError
└─ UnicodeError
├─ UnicodeDecodeError
└─ UnicodeEncodeError
※ 主要なものだけを抜き出した抜粋です。すべての例外はPython公式ドキュメント「組み込み例外 — 例外階層」で確認できます。
親クラスを指定すると、子もまとめて捕まる
except に親クラスを書くと、その下にぶら下がる子クラスもすべて捕まります。よく使う組み合わせは次の通りです。
| 親クラス | まとめて捕まる主な例外 | 使いどころ |
|---|---|---|
LookupError | IndexError / KeyError | リストの添字と辞書のキー、どちらの取り出しミスも同じ扱いにしたいとき |
ArithmeticError | ZeroDivisionError / OverflowError | 計算の失敗をまとめて処理したいとき |
ImportError | ModuleNotFoundError | 「ライブラリが無ければ代替処理」を書くとき |
OSError | FileNotFoundError / PermissionError | ファイル操作の失敗をまとめて処理したいとき |
ValueError | UnicodeDecodeError / UnicodeEncodeError | 値の不正と文字コードの失敗を同じ扱いにしたいとき |
NameError | UnboundLocalError | 実務ではまとめずに、原因を直すほうが先です |
data = {"apple": 100}
items = ["apple"]
# 添字ミスもキーミスも LookupError ひとつで受け止められる
try:
print(items[5])
print(data["banana"])
except LookupError as e:
print(type(e).__name__, e)
# IndexError list index out of range
# ライブラリが無ければ代替処理へ
try:
import ujson as json_lib
except ImportError:
import json as json_lib # ModuleNotFoundError もここで捕まる
except を並べるときは「子 → 親」の順に書く
except は上から順に照合され、最初に当てはまった1つだけが実行されます。そのため親クラスを先に書くと、後ろに書いた子クラスの節には決して到達しません。個別に処理を分けたいときは必ず子を先に書いてください。
try:
[1][9]
except LookupError:
print("LookupError の節が実行される")
except IndexError:
print("ここには絶対に来ない") # IndexError は LookupError の子
try:
[1][9]
except IndexError:
print("IndexError の節が実行される") # こちらが選ばれる
except LookupError:
print("IndexError 以外の取り出しミスはこちら")
階層の一番上は Exception ではなく BaseException です。上の図のとおり KeyboardInterrupt(Ctrl + C)と SystemExit(sys.exit())は Exception の外側にあるため、except Exception: ではこの2つは捕まりません。これは欠点ではなく、Ctrl + C での中断と sys.exit() での終了が邪魔されないようにするための設計です。裸の except: は BaseException を捕まえてしまい、プログラムを止められなくなるので避けましょう(§22もあわせてどうぞ)。
階層上は SyntaxError も Exception の子ですが、自分のファイルに書いた構文エラーは try で囲んでも捕まりません。構文チェックは実行が始まる前に行われるため、try の行に到達する前にプログラムが止まるからです。SyntaxError を except で受け取れるのは、import した別ファイルや compile() で後から読み込むコードに構文エラーがあった場合に限られます。
エラー対処の基本ステップ
- エラーの最終行を読む(エラーの種類と説明)
File "〜.py", line XXでエラー行を確認- エラー行とその前後のコードを確認する
- 変数の型・値を
print()で出力して確認する - それでも解決しない場合はエラーメッセージを検索する
よくある質問(FAQ)
エラーの調べ方について、学習中によく出てくる疑問をまとめました。
Q. エラーメッセージはどこから読めばいいですか?
一番下の行からです。最終行にエラーの種類と内容が書かれているので、まずそこを読みます。次に、下から2つ目の File 行を見れば、どのファイルの何行目で落ちたかが分かります。上から順に読むと呼び出し経路をたどることになり遠回りです。詳しい手順はトレースバックの読み方の章で図解しています。
Q. 英語のエラーメッセージは日本語に翻訳してから検索したほうがいいですか?
翻訳せず、英語のまま検索するのが基本です。エラーメッセージは世界共通の文字列なので、英語のまま検索したほうが情報量が段違いに多くなります。検索するときは、クォートで囲まれた部分(自分の変数名やファイル名)を外して共通部分だけを使い、先頭に python を付けると精度が上がります。
Q. SyntaxError と IndentationError は何が違いますか?
IndentationError は SyntaxError の子クラスで、構文エラーのうち字下げが原因のものだけを指します。つまり IndentationError はすべて SyntaxError の仲間です。さらにタブとスペースが混在している場合は、IndentationError の子である TabError になります。どれも実行が始まる前に検出されるため、1つでもあるとファイルは1行も実行されません。
Q. AttributeError と NameError の違いは何ですか?
ドットの左右で切り分けられます。NameError は名前そのものが存在しないエラーで、prnt("hello") のようなスペルミスで起きます。AttributeError はオブジェクト自体は存在するのに、そのドットより後ろのメソッドや属性が無いエラーで、math.sqr(4) のように起きます。Python 3.10 以降はどちらも Did you mean: の形で正しい候補を提示してくれるので、まずその候補を試すのが早道です。ただし Jupyter・Colab(IPython)では、この候補表示が出ないことがあります。IPython が独自のエラー表示を使うためで、Python公式の「What's New In Python 3.10」にも、独自の表示関数を使う IPython のような REPL では候補が出ない、と注意書きがあります。候補を見たいときは .py ファイルとして実行し直してください。
Q. try / except はいつ使えばいいですか?
起きることが事前に分かっていて、自分のコードでは防げない失敗に使います。ファイルが存在しない、ネットワークがつながらない、利用者が数字以外を入力した、といった外部要因が対象です。逆に、変数名のスペルミス(NameError)や型の取り違え(TypeError)は自分のコードのバグなので、except で隠さずコードを直してください。使うときは except の後ろに例外の種類を必ず書き、何を想定した処理なのかを明示します。
Q. 同じエラーが何度直しても消えないときは何を疑えばいいですか?
直したつもりのコードが実行されていない可能性があります。確認する順番は、ファイルを保存したか、トレースバックの File 行のパスが編集中のファイルと一致しているか、実行している Python が意図した環境かの3点です。3つ目は python -c "import sys; print(sys.executable)" で実際に動いている Python の場所を表示すると確認できます。仮想環境の有効化を忘れているケースがよくあります。
Q. incomplete input という表示は特別なエラーですか?
特別なものではなく SyntaxError の一種です。ただし表示される場所が限られていて、Jupyter Notebook や Google Colab のように内部で IPython を使うセル実行環境で出ます。同じコードをファイルとして実行すると、括弧の閉じ忘れなら '(' was never closed のように、より具体的なメッセージに変わります。原因が分からないときは .py ファイルにコピーして実行し直すと特定が早くなります。
Q. エラーは出ないのに結果が間違っているときはどうすればいいですか?
文法と型は通っていて、考え方のほうが間違っている状態です。この場合 Python は何も教えてくれないので、処理を分割して途中の値を print() で表示し、どこから想定と違うかを挟み撃ちで探します。値だけでなく type() で型も一緒に出すと、文字列と数値の取り違えのような原因に気づきやすくなります。