Pythonのローカル変数とグローバル変数

プログラミング言語の基本要素のひとつに変数がある。簡単に言えば、変数は実際の値を格納するメモリセルの抽象化レイヤーです。私たち開発者にとっては、物理的なメモリアドレスを覚えるよりも、メモリセルの名前を覚える方が簡単です。有効な名前は、数字だけでなく、「a」から「z」までの文字(小文字と大文字の両方)で構成することができます。名前には、スペースや、ウムラウトやハイフンなどの特殊文字は使えません。

さらに、変数は文字列(文字)、数字、リスト、他の変数への参照など、特定のデータ型を持っています。Pythonでは、同じ変数を再利用して、任意の型の値を格納することができます。型は、名前に割り当てられた値によって自動的に決定されます。特定の値を持つ変数を定義するには、次のように名前にその値を代入するだけです。

age = 42
name = "Dominic"
places = ["Berlin", "Cape Town", "New York"]


Python インタープリタは age, name, places という3つの変数を作成し、最初の変数に 42 という値を、2番目の変数に “Dominic” という値を代入し、 places は “Berlin”, “Cape Town”, “New York” という文字列を含む3要素のリストになっています。

名前空間

上記の変数はすべて同じ名前空間に属しており、したがって同じスコープを持っています。後でローカル変数として再定義されない限り、メインプログラムで定義された変数はグローバル名前空間に属し、Pythonプログラムのどの関数からもアクセスできます。次のコード例では、関数 info() の中で nameage という2つの変数を使用して、このことを実証しています。

age = 42
name = "Dominic"
places = ["Berlin", "Cape Town", "New York"]


def info():
    print("%s is %i years old." % (name, age))
    return


info()


出力は、関数 info()print ステートメントから得られる一行からなります。

$ python3 global.py
Dominic is 42 years old.


より正確には、すべてのモジュール、クラス、関数はそれ自身の名前空間を持ち、変数はそれにローカルに束縛されます。次の例では、2つの名前空間を利用しています。メインプログラムの外側のグローバルな名前空間と、単に output() という名前の関数の内側のローカルな名前空間です。変数 place はメインプログラム (6行目) に存在し、関数 output() の2行目で新しい値を持つローカル変数として再定義されます。

def output():
   place = "Cape Town"
   print("%s lives in %s." % (name, place))
   return


place = "Berlin"
name = "Dominic"
print("%s lives in %s." % (name, place))
output()


出力はこの2行からなり、1行目はメインプログラム(8行目)から、2行目は関数 output() の3行目の print ステートメントから出力されています。まず、メインプログラムの中で nameplace という 2 つの変数が定義され (6行目と7行目)、標準出力に出力されます。関数 output() を呼び出すと、2 行目で変数 place がローカルに再定義され、代わりに name がグローバルな名前空間から取得されます。この結果、以下のような出力が得られます。

$ python3 localscope.py
Dominic lives in Berlin.
Dominic lives in Cape Town.


異なるネームスペースのグローバル変数の変更

グローバル変数の値は、プログラム全体を通してアクセスすることができます。これを実現するために、Python では global というキーワードを使用します。以下の関数はその使い方を示しており、変数 name を関数の名前空間にインポートしています。

def location():
    global place
    place = "Cape Town"
    return


place = "Berlin"
print(place)
location()
print(place)


変数 place はメインプログラムの中ですでに定義されています (6行目)。2 行目でキーワード global を使用すると、この変数は関数 location() の中で使用できるようになり、すぐに別の値を設定することができます (3 行目)。このコードの出力は次のとおりです。

$ python3 globalscope.py
Berlin
Cape Town


2行目のようにキーワード global を使用しない場合、変数 place は関数 location() の中でローカル変数として扱われ、メインプログラムの変数 place は変更されません。

変数のスコープを検出する

Python には globals()locals() という名前の 2 つの組み込みメソッドがあります。これらのメソッドにより、ある変数がグローバルネームスペースとローカルネームスペースのどちらに属しているかを判断することができます。以下の例では、これらのメソッドをどのように使用するかを示しています。

def calculation():
    "do a complex calculation"

    global place
    place = "Cape Town"
    name = "John"

    print("place in global:", 'place' in globals())
    print("place in local :", 'place' in locals())
    print("name in global :", 'name' in globals())
    print("name in local  :", 'name' in locals())
    return


place = "Berlin"
print(place)
calculation()


出力は以下のようになり、関数 calculation() 内の 2 つの変数 placename のスコープが表示されます。

$ python3 variablelist.py
Berlin
place in global: True
place in local : False
name in global : False
name in local  : True


グローバル変数の実践的な使用

関数内部でグローバル変数を使用したり変更したりすることは、非常に悪いプログラミングスタイルと見なされており、検出が困難な副作用を引き起こすからです。関数のパラメータを適切に使用することを強くお勧めします。

謝辞

本論文の作成にあたり、Mandy Neumeyerのサポートに感謝したい。

リンクと参考文献

  • Bernd Klein: Global, Local and nonlocal Variables, https://www.python-course.eu/python3_global_vs_local_variables.php
  • Variable scope and lifetime, University of Cape Town, http://python-textbok.readthedocs.io/en/1.0/Variables_and_Scope.html
  • Python 3: globals(), https://docs.python.org/3/library/functions.html#globals
  • Python 3: locals(), https://docs.python.org/3/library/functions.html#locals
タイトルとURLをコピーしました