2015年11月27日

グローバル変数の注意点

Python でグローバル変数を変更する際の注意点を述べます。


グローバル変数をローカルスコープから書き換えるには、スコープ内で "global 変数名" という宣言をする必要があります。
以下は具体的なソースコード例です。

>>> x = 0  # グローバル変数

>>> def func():
...     global x  # グローバル変数を
...               # 取り込むという宣言
...     x = 1
...     print(x)
...
>>> func()
1
>>> x  # グローバル変数も変化
1

この宣言自体はPythonの仕様なのですが、
  • globalという修飾子を使わない言語が多い
  • グローバル変数の読み込みなら宣言不要
上記のような理由のために、しばしば宣言忘れが起こってしまいます。

宣言忘れの結果、見つけにくいバグが埋め込まれることがあります。
以下は、グローバル変数を書き換えたと思ったらローカル変数を新規作成していた、という典型的なバグの例です。func()関数のローカルスコープ内では x が意図通りの振る舞いをするため、一見すると正しい動作に見える点がやっかいです。

>>> x = 0  # グローバル変数

>>> def func():
...     x = 1  # これはローカル
...            # 変数を新規作成
...     print(x)
...
>>> func()
1
>>> x  # グローバル変数は変化なし
0


グローバル変数をローカルスコープから書き換える際は、「スコープ内で global宣言を忘れないように!」というのが本項の結論です。
が、より根本的な話として、グローバル変数の変更はそもそも歓迎されません。「グローバル変数を変更する機会を可能な限り排除する!」これこそ真っ先にやるべきことです。

0 件のコメント:

コメントを投稿