PythonのIndentationErrorとは?原因と直し方を初心者向けに解説

Pythonのコードを実行したとき、次のようなエラーが表示されることがあります。

IndentationError: expected an indented block

「IndentationError」は、コードの字下げに問題があることを示すエラーです。

Pythonでは、行の先頭に入れる空白を使って処理のまとまりを表します。そのため、必要な字下げがなかったり、空白の数がそろっていなかったりすると、プログラムを実行できません。

この記事では、IndentationErrorが起きる主な原因と直し方を、初心者向けに分かりやすく解説します。

この記事の内容

インデントとは

インデントとは、行の先頭に空白を入れて、コードを右側へ下げることです。日本語では「字下げ」とも呼ばれます。

次のコードでは、「print()」の前に空白が入っています。

score = 80

if score >= 70:
    # 条件が成立したときに実行する
    print("合格です")

「if」の条件が成立したときに実行する処理は、「if」の行よりも右側へ下げて書きます。

Pythonでは、この空白が単なる見た目の調整ではありません。「どこからどこまでが同じ処理なのか」を判断するための文法です。

そのため、インデントが正しくないと「IndentationError」が発生します。

expected an indented blockが表示される原因

「expected an indented block」は、必要な場所にインデントされた処理がない場合に表示されます。

例えば、次のコードでは「if」の次の行がインデントされていません。

score = 80

if score >= 70:
# インデントがないためエラーになる
print("合格です")

エラーメッセージは次のようになります。

IndentationError: expected an indented block after 'if' statement

「インデントされた処理が必要です」という意味です。

「print()」の前に空白を入れると修正できます。

score = 80

if score >= 70:
    # ifの内側に入るように字下げする
    print("合格です")

「if」「for」「while」「def」など、末尾にコロンが付く行の次には、基本的にインデントされた処理が必要です。

for文の中身がインデントされていない

IndentationErrorは、「for文」でも発生します。

fruits = ["りんご", "みかん", "バナナ"]

for fruit in fruits:
# 繰り返す処理が字下げされていない
print(fruit)

「print(fruit)」は繰り返し実行する処理なので、「for」の内側へ入れます。

fruits = ["りんご", "みかん", "バナナ"]

for fruit in fruits:
    # リストの要素を順番に表示
    print(fruit)

エラーが発生したら、「コロンの次の行が右へ下がっているか」を最初に確認しましょう。

関数の中身がインデントされていない

「def」で関数を作る場合も、関数内の処理にインデントが必要です。

def greet():
# 関数の中身が字下げされていない
print("こんにちは")

正しくは次のように書きます。

def greet():
    # 関数を呼び出したときに実行する
    print("こんにちは")

greet()

「def greet():」と「print()」の位置が同じだと、Pythonは関数の中身を見つけられません。

関数の中で実行する処理は、同じ幅だけ右へ下げます。

unexpected indentが表示される原因

必要のない場所にインデントがあると、「unexpected indent」が表示されることがあります。

name = "モトヤ"

    # 必要のないインデントが入っている
    print(name)

この「print()」は、条件分岐や繰り返し処理の内側ではありません。そのため、行の先頭に空白を入れる必要がありません。

余分な空白を削除すると修正できます。

name = "モトヤ"

# 左端をそろえる
print(name)

「unexpected indent」は、「Pythonが予想していない場所でコードが右に下がっています」という意味です。

エラーが発生した行だけでなく、その直前に「if」や「for」などの処理があるかも確認しましょう。

unindent does not matchが表示される原因

同じ処理のまとまりで空白の数がそろっていないと、次のエラーが表示されることがあります。

IndentationError: unindent does not match any outer indentation level

例えば、次のコードでは2つの「print()」の位置がずれています。

score = 80

if score >= 70:
    print("合格です")
  # 上の行と空白の数が異なる
  print("次の課題へ進めます")

同じ「if」の中で実行する処理は、インデントの幅をそろえます。

score = 80

if score >= 70:
    # 同じ処理のまとまりは位置をそろえる
    print("合格です")
    print("次の課題へ進めます")

コードが少しずれているだけでも、Pythonでは別の階層として判断されることがあります。

「何個の空白があるか」を目で数えるより、エディターの自動整形機能を利用するほうが確実です。

タブとスペースの混在に注意する

見た目では位置がそろっていても、タブとスペースが混ざっているとエラーになることがあります。

TabError: inconsistent use of tabs and spaces in indentation

「TabError」は、インデントにタブとスペースが一貫せず使われているときに発生します。

例えば、1行目はスペース4個、2行目はタブ1個で字下げされている場合です。エディター上では同じ幅に見えても、Python内部では異なる文字として扱われます。

Pythonのコードでは、「インデントをスペース4個に統一する」のが一般的です。

多くのコードエディターには、タブキーを押したときにスペースへ変換する設定があります。手作業で空白を調整するより、エディター側の設定を統一すると再発を防ぎやすくなります。

インデントは必ずスペース4個でなければならないのか

Pythonの文法上は、インデントが必ずスペース4個でなければならないわけではありません。

次のコードも、同じ階層の幅がそろっているため実行できます。

score = 80

if score >= 70:
  # スペース2個でも文法上は実行できる
  print("合格です")

ただし、Pythonの標準的なコーディング規約では、スペース4個が推奨されています。

複数人でコードを読んだり、あとから自分で修正したりするときのためにも、「スペース4個」に統一するとよいでしょう。

大切なのは、空白の数を毎回変えず、「同じ階層では同じ幅にそろえる」ことです。

入れ子になった処理のインデント

「if」の中に「for」がある場合など、処理が入れ子になるとインデントがさらに深くなります。

scores = [80, 45, 90]

if scores:
    # ifの内側
    for score in scores:
        # forの内側
        if score >= 70:
            # さらにifの内側
            print(f"{score}点は合格です")

このコードには、複数の階層があります。

  • 「for」は最初の「if」の内側
  • 2つ目の「if」は「for」の内側
  • 「print()」は2つ目の「if」の内側

インデントが深くなったときは、「どの行の内側にある処理なのか」を確認しましょう。

「見た目をきれいに並べる」のではなく、「処理の親子関係を表す」という意識が大切です。

処理を書かずに後回しにしたい場合

「if」や関数の中身をあとで書こうとして、何も記述しないとエラーになります。

score = 80

if score >= 70:
# 中身がないためエラーになる

一時的に処理を空にしたい場合は、「pass」を書きます。

score = 80

if score >= 70:
    # 処理はあとで追加する
    pass

「pass」は何も処理をしない命令です。

関数の形だけ先に用意したい場合にも使えます。

def calculate_total():
    # 関数の処理はあとで作成する
    pass

「コメントを書いているから中身がある」と考えやすいですが、コメントだけでは処理として認識されません。実行する命令がない場合は、「pass」が必要です。

コピーしたコードでエラーが出る場合

Webサイトなどからコードをコピーしたとき、インデントが崩れることがあります。

主な原因は次のとおりです。

  • 行の先頭に余分な空白が入った
  • 一部の行だけインデントが消えた
  • タブとスペースが混ざった
  • コードの一部分だけをコピーした
  • 全角スペースが行頭に入った

特に、日本語入力中に入る全角スペースは見つけにくいため注意が必要です。

問題のある範囲を一度左端へ戻し、エディターのタブキーを使ってインデントを付け直すと修正しやすくなります。

コード全体をすぐに書き換えるのではなく、「エラーが示す行の周辺だけを整える」ことから始めましょう。

エラーが示す行だけを見ればよいとは限らない

IndentationErrorに表示される行番号は、Pythonが問題に気づいた場所です。

必ずしも、間違いを最初に書いた場所とは限りません。

score = 80

if score >= 70:
    print("合格です")
  print("処理を終了します")

エラーは最後の「print()」で表示されますが、直すためには「この行をどの処理に含めたいのか」を考える必要があります。

「if」の中で表示したいなら、上の「print()」と位置をそろえます。

score = 80

if score >= 70:
    print("合格です")
    print("処理を終了します")

「if」の外で表示したいなら、左端へ戻します。

score = 80

if score >= 70:
    print("合格です")

# ifの外側で必ず実行する
print("処理を終了します")

正しいインデントは、見た目だけでは決まりません。「どの条件で実行したい処理なのか」によって決まります。

IndentationErrorを直す順番

エラーが発生したときは、次の順番で確認すると原因を見つけやすくなります。

  1. エラーメッセージに表示された行番号を確認する
  2. その行と一つ前の行を見る
  3. コロンの次にインデントがあるか確認する
  4. 同じ処理の行が同じ位置にそろっているか確認する
  5. 不要なインデントが入っていないか確認する
  6. タブとスペースが混ざっていないか確認する
  7. エディターの自動整形を実行する

最初からコード全体を眺めると、どこを直せばよいか分からなくなることがあります。

「エラー行の周辺」「処理のまとまり」「空白の種類」の順に範囲を広げると、効率よく原因を探せます。

IndentationErrorを防ぐ方法

IndentationErrorを減らすには、日頃から書き方を統一することが効果的です。

  • インデントをスペース4個に統一する
  • タブとスペースを混在させない
  • コロンを書いたら次の行をインデントする
  • 同じ階層のコードは縦の位置をそろえる
  • コードエディターの自動インデントを利用する
  • 長い入れ子を作りすぎない
  • コピーしたコードはインデントを確認する

Visual Studio Codeなどのコードエディターでは、インデントを示す縦線や空白文字を表示できます。

エラーが多い場合は、「自分が空白を正確に入力できるか」に頼るのではなく、「エディターに不一致を見つけてもらう」環境を作るとよいでしょう。

まとめ

「IndentationError」は、Pythonのインデントに問題があるときに発生するエラーです。

特に確認したいエラーメッセージは、次の3つです。

  • インデントが必要:「expected an indented block」
  • 不要なインデントがある:「unexpected indent」
  • インデントの幅が一致しない:「unindent does not match any outer indentation level」

タブとスペースが混在している場合は、「TabError」が表示されることもあります。

正しいコードの基本形は次のとおりです。

score = 80

if score >= 70:
    # ifの内側はスペース4個で字下げする
    print("合格です")
else:
    # elseの内側も同じ幅で字下げする
    print("不合格です")

IndentationErrorを直すときは、空白の数だけを見るのではなく、「その行をどの処理の中で実行したいのか」を考えることが重要です。

インデントはコードをきれいに見せる飾りではありません。Pythonに処理のまとまりを伝えるための文法です。

この考え方が分かれば、エラーを直すだけでなく、条件分岐や繰り返し処理の構造も理解しやすくなります。

この記事が役に立ったらシェア
  • URLをコピーしました!
この記事の内容