Global and Local vars. in function
basics
作った変数が関数の外であってもその関数の上で宣言されていればその変数にはアクセス可能
x = 1
def k():
print(x)
k() # 1
「中は中、外は外」といったところでしょうか。
def k():
t = "I love Tokio"
print(t)
t = "I love Osaka"
k() #I love Tokio
print(t) #I love Osaka
白黒はっきりさせたいのがpython
だそうです。
# スクリプト#1
>>> def k():
... print(t)
... t = "I love Tokio"
... print(t)
>>> t = "I love Osaka"
>>> k() # Error
>>> print(t) # I love Osaka
もし関数内でglobal
とlocal
ではっきりさせたいのであれば、global var
と先に宣言する。基本的に関数内で作られた変数はlocal
# スクリプト#2
def k():
global t
print(t)
t = "I love Tokio"
print(t)
t = "I love Osaka"
k() # I love Osaka I love Tokio
print(t) # I love Tokio
スクリプト#1のようにglobal
宣言しないとprint(t)
はglobal var.
であるI love Osaka
を持ってくるのに対して、宣言を行った真上のスクリプトではprint(t)
はlocal var.
であるI love Tokio
になっている。
def k():
s = "I love Tokio"
print(s)
k() # I love Tokio
print(s) # Error
Local var.
は関数の外から持ってこれない。
Pop quiz
それぞれの変数の値は何になるでしょうか?答えはここ。
def foo(x, y):
global a
a = 42
x,y = y,x
b = 33
b = 17
c = 100
print(a,b,x,y)
a,b,x,y = 1,15,3,4
foo(17,4)
print(a,b,x,y)
ちなみに
# スクリプトa
def foo(x, y):
global a
a = 42
x,y = y,x
b = 33
b = 17
c = 100
print(a,b,x,y)
a,b,x,y = 1,15,3,4
foo(17,4)
print(a,b,x,y)
と
# スクリプトb
def foo(x, y):
global a
a = 42
x,y = y,x
b = 33
b = 17
c = 100
print(a,b,x,y)
a,b,x,y = 1,15,3,4
print(a,b,x,y)
ではprint(a,b,x,y)
の結果が若干異なる。スクリプトaではfoo
関数を読んでいるためa
がglobal
宣言され42
という数値を渡されている。スクリプトbではその関数を呼ばないためa
は1
のまま。
追記
Pythonのデコレータを理解するための12Stepをdecoratorについて調べていたら偶然見かけたので一応。
>>> text = "I am global!"
>>> def foo():
... text = "I am local!" #2
... print locals()
...
>>> foo()
{'text': 'I am local!'}
>>> text
'I am global!'
oo()が呼ばれた時にはtextの内容として関数内で代入した値がセットされていますが, 外側のグローバル変数のtextの値は変わっていません. #2では実際のところグローバル変数を探しに行かず, 関数foo内に新しいローカル変数textが作られているのです.
つまり関数の内側ではグローバル変数は参照はできるものの代入はできない, ということになります。
変数のライフタイム
また上と同じ記事の引用だがライフタイムについては全く認識がなかったので引用させていただくことにした。
>>> def foo():
... x = 1
...
>>> foo()
>>> print x #1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
ここでエラーが起こっているのは, 上述のスコープの問題だけではありません. 名前空間は関数fooが呼ばれる都度作られ, 処理が終わると無くなってしまいます.つまり上の例では#1のタイミングでは文字通りxという変数はどこにも存在していない, ということです.
引用がちょっと多めな投稿になってしまいました。。