Python - 言語 - 関数 - 変数のスコープ
*
変数のスコープ
局所(ローカル)変数
- 局所(ローカル)変数
- 関数の内部で定義された(代入された)変数
- 同名の変数が,関数の外側で定義されていても構わない
- 関数の外側の同名変数と,関数の内側の同名変数は,別々のスコープとなる
- 外部に同名の変数があろうがなかろうが,関数内で変数に代入が起こった時点で,その変数はローカル変数となる
- ローカル変数であれば,定義(最初の代入)が起こる前に使用されてはならない
- 同名の変数が,関数の外側で定義されていても構わない
- 関数の内部で定義された(代入された)変数
- 大域(グローバル)変数
- 関数の外部で定義された(代入された)変数
- 関数の中でグローバル変数を参照することはできる
- 後述のglobal宣言をしなければ,関数の中で,代入することはできない
- 後述のglobal宣言をすれば,関数の中での代入で,関数外に副作用を残すことができる
- 関数の中でグローバル変数を参照することはできる
関数globals()
グローバル変数の一覧を含む名前辞書
関数locals()
ローカル変数の一覧を含む名前辞書
- 関数の外部で定義された(代入された)変数
局所変数と大域変数の共存
関数の呼び出し前のメインでの値
関数の実行終了時の関数内での値
関数の呼び出し後のメインでの値
大域変数
x1, x2, x3, x4
10, 20, 30, 40
10, 20, 30, 40
10, 20, 30, 40
局所変数
x1, x2
100, 200
1 # global_test_01.py
2 ## (大域変数と局所変数が使い分けられている例)
3 ## (但し関数内では,大域変数は参照しても,代入はできない)
4
5 def func():
6 print( "---- 関数の中 (はじめ) -----" )
7 x1 = 100 # <------------ (f1) 局所変数x1の定義
8 x2 = 200 # <------------ (f2) 局所変数x1の定義
9 print( "x1 = ", x1 ) # <------------ (f3) 局所変数x1が参照される
10 print( "x2 = ", x2 ) # <------------ (f4) 局所変数x2が参照される
11 print( "x3 = ", x3 ) # <------------ (f5) 大域変数x3が参照される
12 print( "x4 = ", x4 ) # <------------ (f6) 大域変数x4が参照される
13 print( "globals = ", globals() )
14 print( "locals = ", locals() )
15 print( "---- 関数の中 (おわり) -----" )
16
17 print( "---- メイン (関数呼び出し前) -----" )
18 x1 = 10 # <------------ (m1) 大域変数x1の定義
19 x2 = 20 # <------------ (m2) 大域変数x2の定義
20 x3 = 30 # <------------ (m3) 大域変数x3の定義
21 x4 = 40 # <------------ (m4) 大域変数x4の定義
22
23 print( "x1 = ", x1 ) # <------------ (m5) 大域変数x1が参照される
24 print( "x2 = ", x2 ) # <------------ (m6) 大域変数x2が参照される
25 print( "x3 = ", x3 ) # <------------ (m7) 大域変数x3が参照される
26 print( "x4 = ", x4 ) # <------------ (m8) 大域変数x4が参照される
27 print( "globals = ", globals() )
28 print( "locals = ", locals() )
29 # -------------------------------------------------------
30 func()
31 # -------------------------------------------------------
32 print( "---- メイン (関数呼び出し後) -----" )
33 print( "x1 = ", x1 )
34 print( "x1 = ", x2 )
35 print( "x1 = ", x3 )
36 print( "x1 = ", x4 )
37 print( "globals = ", globals() )
38 print( "locals = ", locals() )
39 print( "---- メイン (おわり) -----" )
> python global_test_01.py ---- メイン (関数呼び出し前) ----- x1 = 10 x2 = 20 x3 = 30 x4 = 40 globals = { ... (中略)... 'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} locals = { ... (中略)... 'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} ---- 関数の中 (はじめ) ----- x1 = 100 x2 = 200 x3 = 30 x4 = 40 globals = { ... (中略)... 'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} locals = {'x2': 200, 'x1': 100} ---- 関数の中 (おわり) ----- ---- メイン (関数呼び出し後) ----- 10 20 30 40 globals = { ... (中略)... 'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} locals = { ... (中略)... 'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} ---- メイン (おわり) -----
局所変数と大域変数の共存できていない
- 関数の中で先に代入せずに参照されてしまうと,その変数は,大域変数とみなされるので,局所変数として関数内で値を代入できない
- 下記(f1)とf(3),(f2)とf(4)が,矛盾しているため
1 # global_test_02.py
2 ## (実行時エラーが発生する例)
3 ## (但し関数内では,大域変数は参照しても,代入はできない)
4
5 def func():
6 print( "---- 関数の中 (はじめ) -----" )
7 print( "x1 = ", x1 ) # <------------ (f1) 大域変数x1が参照される
8 print( "x2 = ", x2 ) # <------------ (f2) 大域変数x2が参照される
9 x1 = 100 # <------------ (f3) x1は既に大域変数として使用されているので,局所変数とできない
10 x2 = 200 # <------------ (f4) x2は既に大域変数として使用されているので,局所変数とできない
11 print( "x3 = ", x3 ) # <------------ (f5) 大域変数x3が参照される
12 print( "x4 = ", x4 ) # <------------ (f6) 大域変数x4が参照される
13 print( "globals = ", globals() )
14 print( "locals = ", locals() )
15 print( "---- 関数の中 (おわり) -----" )
16
17 print( "---- メイン (関数呼び出し前) -----" )
18 x1 = 10
19 x2 = 20
20 x3 = 30
21 x4 = 40
22 print( "x1 = ", x1 )
23 print( "x2 = ", x2 )
24 print( "x3 = ", x3 )
25 print( "x4 = ", x4 )
26 print( "globals = ", globals() )
27 print( "locals = ", locals() )
28 # -------------------------------------------------------
29 func()
30 # -------------------------------------------------------
31 print( "---- メイン (関数呼び出し後) -----" )
32 print( "x1 = ", x1 )
33 print( "x2 = ", x2 )
34 print( "x3 = ", x3 )
35 print( "x4 = ", x4 )
36 print( "globals = ", globals() )
37 print( "locals = ", locals() )
38 print( "---- メイン (おわり) -----" )
>python global_test_02.py ---- メイン (関数呼び出し前) ----- x1 = 10 x2 = 20 x3 = 30 x4 = 40 globals = { ... (中略)...'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} locals = { ... (中略)...'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} ---- 関数の中 (はじめ) ----- Traceback (most recent call last): File "global_test_02.py", line 29, in <module> func() File "global_test_02.py", line 7, in func print( "x1 = ", x1 ) # <------------ (f1) 大域変数x1が参照される UnboundLocalError: local variable 'x1' referenced before assignment
大域(グローバル)変数
- 大域(グローバル)変数
- 関数の外部で定義された(代入された)変数
- 関数の中でグローバル変数を参照することはできる
- 関数の外部で定義された(代入された)変数
大域(グローバル)変数への代入(global宣言)
- 大域(グローバル)変数への代入
- 関数の外部で定義された変数
- 関数の中でグローバル変数を参照することはできる
- global宣言すれば,関数の中で,代入することができる
- 関数の外部で定義された変数
例: global宣言を行った例
関数の呼び出し前のメインでの値
関数の実行終了時の関数内での値
関数の呼び出し後のメインでの値
大域変数
x1, x2, x3, x4
10, 20, 30, 40
100, 200, 30, 40
10, 20, 30, 40
局所変数
x1, x2
1 # global_test_03.py
2 ## (global宣言する例)
3
4 def func():
5 print( "---- 関数の中 (はじめ) -----" )
6 global x1, x2 # <------------ (f0) global宣言: 変数x1とx2は大域変数
7 print( "x1 = ", x1 ) # <------------ (f1) 大域変数x1が参照される
8 print( "x2 = ", x2 ) # <------------ (f2) 大域変数x2が参照される
9 x1 = 100 # <------------ (f3) x1は既に大域変数として使用されているので,局所変数とできない
10 x2 = 200 # <------------ (f4) x2は既に大域変数として使用されているので,局所変数とできない
11 print( "x3 = ", x3 ) # <------------ (f5) 大域変数x3が参照される
12 print( "x4 = ", x4 ) # <------------ (f6) 大域変数x4が参照される
13 print( "globals = ", globals() )
14 print( "locals = ", locals() )
15 print( "---- 関数の中 (おわり) -----" )
16
17 print( "---- メイン (関数呼び出し前) -----" )
18 x1 = 10
19 x2 = 20
20 x3 = 30
21 x4 = 40
22 print( "x1 = ", x1 )
23 print( "x2 = ", x2 )
24 print( "x3 = ", x3 )
25 print( "x4 = ", x4 )
26 print( "globals = ", globals() )
27 print( "locals = ", locals() )
28 # -------------------------------------------------------
29 func()
30 # -------------------------------------------------------
31 print( "---- メイン (関数呼び出し後) -----" )
32 print( "x1 = ", x1 )
33 print( "x2 = ", x2 )
34 print( "x3 = ", x3 )
35 print( "x4 = ", x4 )
36 print( "globals = ", globals() )
37 print( "locals = ", locals() )
38 print( "---- メイン (おわり) -----" )
>python global_test_03.py ---- メイン (関数呼び出し前) ----- x1 = 10 x2 = 20 x3 = 30 x4 = 40 globals = { ... (中略)...'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} locals = { ... (中略)...'x1': 10, 'x2': 20, 'x3': 30, 'x4': 40} ---- 関数の中 (はじめ) ----- x1 = 10 x2 = 20 x3 = 30 x4 = 40 globals = { ... (中略)...'x1': 100, 'x2': 200, 'x3': 30, 'x4': 40} locals = {} ---- 関数の中 (おわり) ----- ---- メイン (関数呼び出し後) ----- x1 = 100 x2 = 200 x3 = 30 x4 = 40 globals = { ... (中略)...'x1': 100, 'x2': 200, 'x3': 30, 'x4': 40} locals = { ... (中略)...'x1': 100, 'x2': 200, 'x3': 30, 'x4': 40} ---- メイン (おわり) -----
リファレンス
Software Engineering(IIJIMA, Tadashi -- Keio Univ.)