Pythonでネストした関数とスコープ

他の言語ばっか触ってるとすぐに忘れてるのでメモ。日本酒3合ぐらい飲みながら書いてるので変なこと書いてるかも。

Pythonでは以下のコードを実行するとUnboundLocalException(変数が定義されてねーぞ例外)が出る。

def foo():
  x = 0
  def bar():
    x += 1  # ここでエラー
  bar()

foo()

ちなみに以下のコードだと大丈夫。

def foo():
  x = 0
  def bar():
    print x
  bar()

foo()

ローカル変数に対しての代入(bind)はOKだけど、スコープの外側の変数はreadonlyですよ(ローカル変数が定義されていない場合のみ外側のブロックの変数を探しに行く)、ということですね。

前者が例外吐くのは、ブロック内で定義されてないものに対して+=演算子を使っちゃってるから。