Pythonの変数のスコープについてなぜグローバル変数を用いるためにglobalをつける必要があるか考察してみた。
まず、C言語の関数から見てみよう
int func()
{
int L;
L = 23;
printf("%d%s", L, G); //出力:"23bit"
}
C言語において、変数は「Use with definition」である。
この関数を見て分かることは変数Lがローカルで宣言されているため、ローカル変数であり、変数Gはローカルではないということである。
次に、VBの関数を見てみよう。
Sub func
L = 23
print L & G ’出力:"23bit"
End Sub
VBにおいて、Option Explicitをつけない場合、変数は「Use without definition」である。
この関数をみて分かる事はLはローカル変数かもしれないし、グローバル変数かもしれない。
(グローバル変数として動いた気はするけども、参照が他になければローカル変数と変わらない)
Gは確実にグローバル変数であるということである。
なぜなら、G="bit"であり他所で確実に設定されているためである。
これを逆説的に言うと、関数内を見渡して未設定で参照のみの変数が使われている場合、ローカル変数では有りえない。ということである。
いよいよPythonの関数を見てみよう
def func():
L = 23
print L,G #出力:"23bit"
Pythonにおいて、変数は「Use with definition. But writing is definition.」である。
なんとなく、CとVBの両方の経験者は「Use without definition」と捕らえてしまいがちであるが、よくよくググってみても変数を宣言しなくても使えると書いているサイトは見当たらない。
関数内を見渡して、Lはここで値を設定しているのでローカル変数であり
Gは値を設定していないのでローカル変数ではない。
もっと言えば、VBにおいて、Gがローカル変数ではない理由は動かすか、グローバル変数宣言部を見るかしないと分からない。
しかし、Pythonの場合、関数func内をみるだけで完結する。
このように、ローカル変数が未設定で参照のみが行われることはないという特徴をグローバル変数と見做すというのは非常に上手いやりかたに思える。
実際に変数Gには何が設定されているのか知りたければGで検索すれば設定場所がひっかかる。
def func2():
global G
G = "bit"
global変数に値を設定する場合、ローカル変数の「値を設定して使う」というルールに参加させるため、globalキーワードを用いる。
これで、どれだけグローバル変数Gが多くの箇所で使われていようが設定している箇所をすべて見つけることができるのである。
なぜ、こんな仕様になったのか考えてみると、システム屋ではない人が作ってもPythonは整った文になるように設計されているということである。
意外と素人に多いコーディングは、めんどくさいから取り敢えずローカル変数をグローバル変数に 持っていくというものである。一番ひどい場合、ループ変数さえも持っていくのである。
しかし、グローバル変数にループ変数を宣言したところでそれを使うのがめんどくさいのがPythonの特徴である。
ローカル変数宣言の1行を省略できるのにglobalを付けてグローバルのループ変数をわざわざ宣言して使う人は少ないだろう。
さらに次のルールが生まれる。
◎1ソースであれば、グローバル変数名で検索して見つかった箇所が全て関数内でのみ、かつglobalキーワードが使われていない場合、グローバル変数は未使用である。
◎globalキーワード付変数を使わない関数を、他のソースに流用した場合において、ローカル変数名とグローバル変数名がたまたま一致したために、ローカル変数への代入がグローバル変数の更新に繋がることはない。
とてもよく考えられているルールではないだろうか?
[0回]
PR