【Python入門】Pythonにおける変数のスコープと名前解決とLEGBルールについての初歩的解説

Python入門:変数のスコープとLEGBルールについての基本的イメージの解説

今回はPythonにおける変数の名前についてのお話です。もしコード内部で同じ名前の変数を使ってしまったらどうなるのでしょう?

そしてその場合、同じ名前の変数の取り扱いをどのようにPythonは処理するのでしょう?

上書き?優劣をつける?それとも最初からエラーとして動作させない?

同じ名前の変数があった場合にPythonがどのように処理していくのか、その基本を大雑把ではありますが簡単に説明します。

Pythonと変数のスコープと名前解決

同じ名前の変数が複数箇所にあったとき、その優先順位は?

まずは同じ名前の変数を使った以下のコードを見てください。

x=10
y=501
z=42
def fnc_01():
    y=9
    z=30
    def fnc_02():
        z=8
        print(x)
        print(y)
        print(z)
    return fnc_02()
        
fnc_01()

結果は下のようになりますl.

10  # xの値
9  # yの値
8  # zの値

以上の結果について簡単に表にしました。

xの値一番上の変数xの値
yの値fnc_01内の変数yの値
zの値fnc_02内の変数zの値

このような対応関係になっています。

これをふまえて今回の結果を説明すると、大雑把にいえば、

同じ名前の変数がある場合は、最も内側にある変数がまず優先される

ということですね。

LEGBルールとは?

Pythonが同じ名前の変数がある場合にどのように処理するのか(名前解決)かは、LEGBというプログラミングの世界の共通規格(?)にもとづいて判断されます。

Pythonの変数のスコープとLEGBルール

LEGBとは、

  • ローカル(Local)
  • エンクロージング(Enclosing)
  • グローバル(Global)
  • ビルトイン(Built-in)

の頭文字です。

そして判断の順番は、まずLが最優先で、次にE、そしてG、最後にBという順番でなされます。したがってその順番どおりにLEGBと呼称されます。

以下の画像を見てください。

Pythonの変数のスコープとLEGBルール

これまでの説明でも理解されているかもしれませんが、あえて再びこのLEGBの内容を説明します。

まず大雑把にいえば、ローカルかグローバルかは、そのPythonファイル内に関数が宣言されているかどうかで決まります。関数の管理領域(ブロック:def宣言のブロック)がローカル。それ以外がグローバルです。

次にローカルとエンクロージングですが、これは関数がネスト(入れ子構造・関係)になっている場合に、最も内側の関数の管理領域(ブロック)がローカル。その関数を内包している外側の関数の管理領域(ブロック)がエンクロージングとなります。

最後にビルトインですが、これは複数のPythonファイルの全てに共通して使われるbuilinsという名称のモジュールによって提供・管理される領域(空間)のことです。

このbuiltinsモジュールは実は最初から標準でPythonに組み込まれているため、import文を使ってインポートする必要はありません。もちろんimport文でインポートしてもかまいませんが(上画像でカッコ書きにしてあるのはそういうことです)。

PythonのファイルAでもファイルBでも、bulitinsモジュールは自動的に最初から組み込まれているため、そのモジュールを使う以上はどちらのファイルでも、そのモジュール内で使われる変数の情報は共通します。

このように複数のPythonファイルの間で共通して使われる変数の情報の領域(空間)がビルトインなのですね。

以上、Pythonにおいて同じ名前の変数があった場合にそれをPythonがどのように扱うのか、そしてそれが従うLEGBというルールとは何かについて説明しました。大雑把で初歩的な説明ですが、それでもこれからPythonのコードや解説を読むことが少し楽になると思います。

プログラミングを学びIT業界へ転職するなら現役エンジニアから学べるプログラミングスクールTechAcademy [テックアカデミー]でオンライン講座を受講するのが良いと思います。1人で悩みながら学習を進めるよりもわかりやすく、費やす時間も少なく合理的・効率的に学習できるからです。

など各種の講座が用意されています。無料で体験できるテックアカデミー無料体験も用意されています。

One comment

Comments are closed.