Pythonの変数スコープについてまとめ

更新日 : 2023/10/24

仕事でよくPythonを使うので、最近改めてPythonを勉強し直しています。
変数のスコープは無意識に考慮してプログラムを書いてはいますが、ちゃんと整理したことはなかったので簡単にまとめてみます。

目次

    グローバルで定義した変数の参照

    まず、基本中の基本ですが以下のようにグローバルに定義した変数はどんなに深い階層からでも参照することができます。
    1a = 10
    2
    3def function():
    4    print(a)
    5    
    6    def function2():
    7        print(a)
    8
    9# 以下のように表示される
    10# 10
    11# 10

    一方、以下のようにグローバル変数の値を普通に書き換えようとしても書き換えることはできません。
    1a = 10
    2
    3def function():
    4    a = 20 # 変数aを書き換えようとしてみるが、、
    5    print(a)
    6    
    7function()
    8print(a)
    9
    10# 以下のように表示される
    11# 20
    12# 10

    グローバルな変数を書き換える場合は以下のように書く必要があります。
    1a = 10
    2
    3def function():
    4    global a # グローバル変数aを使用することを明示
    5    a = 20 # グローバル変数aを書き換える
    6    print(a)
    7    
    8function()
    9print(a)
    10
    11# 以下のように表示される
    12# 20
    13# 20

    ローカルで定義した変数の参照

    また基本中の基本ですが、関数内で定義したローカルの変数は関数外から参照することはできません。(慣れればこのミスはあまりない気もしますね、、、)
    1def function():
    2    a = 100
    3
    4print(a) # NameErrorが起きる

    ブロックスコープについて

    C++やJavaではブロックスコープと呼ばれるものがあり、ifやforなどのブロック内で定義した変数はそのブロック外から参照することはできません。
    しかしPythonにはブロックスコープの概念がないため、ifやfor、whileの中で定義した変数であれば外部から参照することが可能です。
    1if true:
    2    a = 2
    3
    4print(a) # 2と表示される
    ただ、当たり前ですが上記の例だとifに入らなかった時はNameErrorで異常終了するので、ifに入らない場合用の何かしらの対策が必要ですね。

    最後に

    変数のスコープはプログラムにおいて当然のこと過ぎてあまり意識してきませんでしたが、改めて見直して勉強になりました。
    それでは!