ブロックスコープはない
したがって、if文やfor文などの制御構文はスコープを持たない。制御文の外で定義された変数は制御文内で参照でき、制御文内での変更は変数に影響を与える。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
a = 1 if True: print(a) # 1 a += 1 print(a) # 2 print(a) # 2 for i in [1]: print(a) # 2 a += 1 print(a) # 3 print(a) # 3 |
関数のスコープ
関数内では変数はローカルスコープを持つ。
- グローバル変数は関数内から直接には参照できないため、無定義で参照しようとするとエラーとなる
- 関数内でグローバル変数と同じ名前の変数を定義すると、ローカル変数として扱われる
- ローカル変数の変更は、同名のグローバル変数に影響を与えない
1 2 3 4 5 6 7 8 9 10 |
g = 1 def func(): # print(g) # UnboundLocalError: local variable 'g' referenced before assignment g = 2 print(g) # 2 (when called later) func() # 2 print(g) # 1 |
クラスのスコープ
クラスはローカルのスコープを持つが、クラス変数とインスタンス変数でもスコープが異なる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
g = 1 class MyClass: print(' 1:',g) g = 10 print(' 2:', g) def __init__(self): self.g = 100 print(' 3:', g) print(' 4:', MyClass.g) MyClass.g = 50 print(' 5:', MyClass.g) print(' 6:', g) g = 5 print(' 7:', g) print(' 8:', MyClass.g) instance = MyClass() print(' 9:', instance.g) print('10:', MyClass.g) print('11:', g) # 実行結果 # 1: 1 クラス変数はグローバル変数の値を引き継ぐ # 2: 10 クラス変数の値を変更しても # 3: 1 グローバル変数は影響を受けない # 4: 10 クラス変数はクラススコープ # 5: 50 クラス変数を外から変更しても # 6: 1 グローバル変数は影響を受けない # 7: 5 グローバル変数を変更しても # 8: 50 クラス変数は影響を受けない # 9: 100 インスタンス生成時にインスタンス変数を定義 # 10: 50 インスタンス変数はクラス変数とは別のスコープ # 11: 5 グローバル変数とも別のスコープ |
global宣言
グローバル変数をglobal宣言することで、関数の中で参照・変更が可能となる。
1 2 3 4 5 6 7 8 9 10 |
g = 1 def func(): global g print(g) # 1 g += 1 print(g) # 2 func() print(g) # 2 |