変数スコープは、Pythonプログラマーが変数や関数を扱う前に知っておかなければならない、興味深く、便利で、理解しやすい概念です。
この記事では、スコープとは何か、python が持つスコープの種類、そしてキーワードである global
と nonlocal
について説明します。
この記事もチェック:Pythonでの変数の定義やスコープ、削除、globalキーワードを解説していく
スコープって何?
関数やクラス、ユーザー定義変数のスコープとは、その変数にアクセスできるコードの領域のことです。
関数内で宣言された変数は、その関数の中でのみアクセス可能で、関数の外ではアクセスできませんので、その関数が変数のスコープとなります。
たとえば、次のようなコードです。
def funcx():
x = 1
print (x)
return
def funcy():
y = 2
print (y)
return
def funcz():
z = 3
print (z)
return
|
変数 x
は funcx
で宣言されているので、funcx
がその変数のスコープになります。
同様に、y
のスコープは funcy
で、z
のスコープは funcz
です。
この記事もチェック:Pythonでinput関数を使ってユーザーからの標準入力を変数に格納する方法
グローバル変数、ローカル変数、非ローカル変数のスコープを理解します。
Pythonでは、各変数に変数スコープがあります。
つまり、その変数が使用できる境界線が明確に定義されています。
変数が使用される場所によって、変数は異なる種類のスコープを持つことができるので、一つずつ説明しましょう。
1. グローバル変数スコープ
Pythonファイルのどこからでもアクセスできる変数をグローバルスコープと呼びます。
以下のコードを参照してください。
x = 10
print (x)
def func():
print (x)
return
func() |
変数 x
はどの関数の外でも宣言されています。
これは、コード全体のどこからでもアクセスできることを意味します。
上の例では、x
は func
の中だけでなく、func
の外側からもアクセスされます。
出力は
Global: 10
Local: 10
注意: 関数の内部でグローバル変数を操作するのは少し複雑なので、後ほど global
キーワードを使用して説明します。
2. ローカル変数スコープ
ある関数の内部で宣言された変数をローカルスコープと呼びます。
この場合、その変数はその関数内でのみアクセス可能であり、関数の外でそのような変数にアクセスしようとすると、同じ名前のグローバル変数がない場合はエラーになる。
def func():
x = 10
print (x)
|
上の関数では、変数 x
は関数の内部で作成されているので、 x
は func
のローカル変数となります。
したがって、x
は func
のローカル変数です。
func
の外部から x
にアクセスしようとすると、エラーになります。
3. 非局所変数のスコープ
非局所変数のスコープを理解するために、例を挙げよう。
def outer_func():
x = 10
print ( "Outside:" , x)
def inner_func():
print ( "Inside:" , x)
return
inner_func()
return
outer_func() |
関数 outer_func
には変数 x
があるので、明らかに outer_func
にとっては x
はローカルです。
しかし、 inner_func
にとって、 x
は非局所的です。
つまり、 x
は inner_func
にとって局所的ではありませんが、大域的でもありません。
つまり、 inner_func
からは、 x
を非ローカル変数としてアクセスすることができる。
そして、これが出力です。
Outside: 10
Inside: 10
Note: inner_func
から x
を操作するのは少し複雑です。
これは、nonlocal キーワードについて説明するときにわかります。
グローバル変数と非ローカル変数の操り方
関数内でグローバル変数や非ローカル変数にアクセスできることはわかりましたが、関数内でその変数を直接操作しようとすると、エラーになります。
例を見てみましょう。
x = 10
def func():
x + = 1
print (x)
return
func() |
論理的には、グローバル変数であり、どこにでもアクセスできるので、x
を増加させることができるはずですが、実際の出力はこのようになっています。
---------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
<ipython-input-33-07e029a18d76> in <module>
5 return
6
----> 7 func()
<ipython-input-33-07e029a18d76> in func()
1 x = 10
2 def func():
----> 3 x += 1
4 print(x)
5 return
UnboundLocalError: local variable 'x' referenced before assignment
UnboundLocalError: local variable ‘x’ referenced before assignment`と表示されています。
Python は x
がローカル変数であると仮定して、参照する前に値を代入するように言っています。
x` を出力すればうまくいくことは分かっているので、グローバル変数が関数内で直接変更された場合にこのようなエラーが発生することを意味しています。
Pythonのグローバルキーワード
このエラーを回避するために、グローバル変数のスコープに global
キーワードを使用することができます。
x = 10
def func():
global x
x + = 1
print (x)
return
func() |
関数内で x
をグローバルに宣言し、Python に x
がすでにグローバルスコープで宣言されているので、その x
を使用することを伝えていることがわかります。
11
このように、今回は変更された x
の値が出力されます。
Pythonのnonlocalキーワード
非ローカル変数のスコープでは、以下のように nonlocal
キーワードを使用して、説明したエラーを回避します。
def outer_func():
x = 10
def inner_func():
nonlocal x
x + = 1
print (x)
inner_func()
return
outer_func() |
これは inner_func
関数の内部で x
が nonlocal であることを Python に伝えています。
(xはグローバルではないので、global
は機能しません)。
出力は
11
おわりに
この記事では、Python のスコープが何を意味するのか、さらにグローバル、ローカル、非ローカル変数が何であり、どのように使用するのかを説明しました。
また、2つのキーワードの使い方を説明しました。
グローバル(global)」と「非ローカル(nonlocal)」という2つのキーワードの使い方を説明し、Pythonのコードでそれらが動作する様子とその出力を見ました。