変数と関数を理解し、より複雑なプログラムに挑戦する前に『スコープ(Scope)』について理解しておく必要があります。
モジュールやオブジェクト指向にステップアップする前に知っておくと、スムーズな学習に役立ってくれるでしょう。
スコープを理解してコードの読解力を上げよう
スコープとは
スコープは、プログラムの有効範囲を示す言葉で、「ローカルスコープ」や「グローバルスコープ」「ビルトインスコープ」と3種類に分類されます。
一つのPythonファイルで収まるような小規模なプロジェクトであればそれほどスコープを意識する必要はありませんが、複数のPythonファイルが登場するような規模のプロジェクトになると「スコープ」を意識する必要が。
例えば、機械学習などのプロジェクトやゲーム系のプロジェクト、Webサービスなどです。

上図のピンボールゲームの場合、起動プログラム breakout.py を見てみると複数のPythonファイルから機能(関数)を読み込んでいることが分かります。
こうした場合、単に関数の作成方法だけ気をつければOKでしょうか?
例えば、あるファイルの関数名と違うファイルの変数名が一緒だった場合、エラーを誘発します。
下記にサンプルをご紹介。
name = "oshima"
old = 37
def old():
olds = 11
print(olds)
old()
print(name,old)

この場合は、関数名を old_after() などにすればエラーを回避できますね。この仕組みを理解するにはスコープの理解が必要となってきます。
プログラムとスコープ

いきなりですがPyhtonプログラムには見えない線があります。それは各スコープを区切る線で上図のように表せますね。
■ビルトインスコープ■
ビルトインスコープは、Pythonプログラムの中に常に存在するスコープで、通常は意識する必要はありません。組み込み関数や組み込み変数などがビルトインスコープにあたり、代表的なものでは print() や open() がありますね。
差し当たっては、組み込み関数の名前を関数や変数に名づけしない、という点だけ覚えておくといいでしょう。
■グローバルスコープ■
グローバルスコープは、作成するPythonファイル、Pyhtonプロジェクト全域で有効な領域。
グローバルスコープで定めた変数は、グローバルスコープとローカルスコープの両方で有効。
イメージとしては絶対的な変数で、APIのURLや読み込みファイルのファイル名などが使われますね。
参考書によっては「モジュールスコープ」としてグローバルスコープのことを説明しています。

■ローカルスコープ■
ローカルスコープは、関数定義した時に発生するスコープで def ●●(): を書く度に気をつける必要があります。
ローカルスコープで設定する変数は、そのローカルスコープ内のみで有効で、設定したローカルスコープの外で使うことはできません。またグローバルスコープで定めているグローバル変数と同じ名前のローカル変数名を付けることはできない特徴があります。
今回ご紹介しているスコープの中で、最も制約のあるスコープといえるでしょう。
<< ローカル変数をグローバルスコープで実行した場合 >>

<< ローカル変数を異なるローカルスコープで実行した場合 >>

<< あえてローカル変数名とグローバル変数名を一緒に >>

こうしてスコープを整理してみますと、実際にプログラムする時にどんな変数名、関数名をつけたらいいか、迷いますよね。
こうした問題を解決する一つの方法としては、グローバルスコープとローカルスコープで定められている変数一覧を見てみるとエラーを未然に防げるでしょう。
グローバルスコープとローカルスコープの変数一覧は、globals() や locals() で確認できます。

LEGBルール

今までご紹介してきたスコープのルールは、LEGBルールとしてまとめられています(著書 はじめてのPython)。
- L/ Local / ローカルスコープ
- E/ Enclosign Local / def などの領域
- G/ Global / グローバルスコープ
- B/ Built-in / ビルトインスコープ
EのEnclosign Local(エンクロージング)についてはご紹介していませんでしたが、関数宣言の def や lambda がこれに該当。
スコープで困った時に基本ルールを思い出して、プログラミングを楽しみたいですね。
Pythonのスコープルールは参考書を読んでいる内は大丈夫と思うのですが、実際にプログラムを書いてみると「結構複雑だなぁ」ということに気づくと思います。
今回ご紹介させて頂いたサンプルコードはどれもシンプルで比較的分かりやすいのですが、実際のプロジェクトのコードを見ると関数内関数(ネストスコープ)やモジュール化されたプログラムなど複雑。
そのためコードを読解する時には「スコープ」の知識は必須といえるでしょう。
スコープ以前に、「変数や関数がよく分かっていない」「一人ではムリ〜」という方、オンラインのマンツーマンレッスン「CodeCamp」はいかがでしょうか?
時間と場所の制約を受けにくいオンラインレッスンは、忙しいあなたにピッタリかもしれませんよ。無料体験も実施していますのでお気軽にご利用下さい!
