global変数
前回、datetime.timedeltaによる日時の足し算・引き算、秒への変換に関して解説しました。
今回はPythonのグローバル(global)変数に関して解説をしていきます。
あまり普段気にせず使っている変数ですが、実はアクセスできる範囲によってグローバル変数とローカル変数が存在します。
グローバル変数はどこからでもアクセス可能な変数で、ローカル変数は特定の範囲でしかアクセスできない変数です。
例えばnum1という変数とnum2という変数を使ったこんなプログラムを書いてみます。
num1 = 10
def plus():
num2 = 20
return num1 + num2
print(plus())
print(num1)
print(num2)
実行結果
30
10
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [1], in <cell line: 9>()
7 print(plus())
8 print(num1)
----> 9 print(num2)
NameError: name 'num2' is not defined
num1は関数の外で定義されており、num2は関数plusの中で定義されています。
この場合、num1に対しては関数の外でも中でもアクセスすることができるグローバル変数として定義されます。
num2に対しては関数plusの中でのみアクセスでき、外からはアクセスできないローカル変数として定義されます。
今回はこのグローバル変数の使い方を見ていきましょう。
グローバル変数の基礎
先ほどの例をもう一度見てみます。
num1 = 10
def plus():
num2 = 20
return num1 + num2
print(plus())
実行結果
30
先ほどお話しした通り、関数の外で定義されているnum1はグローバル変数、関数plusの中で定義されているnum2はローカル変数です。
通常関数の外から中に値を持ち込む際には引数を利用して、このように記述します。
num1 = 10
def plus(num1):
num2 = 20
return num1 + num2
print(plus(num1))
実行結果
30
このように引数として明示する方がどのような値をどこから持ってきているのか分かりやすいのですが、先ほどのようにわざわざ明示しなくても値にアクセスできるのがグローバル変数のメリットです。
例えばこちらの例のように複数の関数があったとしてもどの関数からでもアクセス可能です。
num1 = 10
def setting():
print(num1)
def plus():
num2 = 20
return num1 + num2
setting()
print(plus())
実行結果
10
30
しかし関数plusで定義されているnum2を関数settingに移動させると、関数plusからはアクセスできなくなるためエラーになります。
num1 = 10
def setting():
print(num1)
num2 = 20
def plus():
return num1 + num2
setting()
print(plus())
実行結果
10
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
Input In [3], in <cell line: 11>()
8 return num1 + num2
10 setting()
---> 11 print(plus())
Input In [3], in plus()
7 def plus():
----> 8 return num1 + num2
NameError: name 'num2' is not defined
ここまでグローバル変数はどこからでも「アクセスできる変数」とお話ししましたが、どういったアクセスができるのかには少し注意が必要です。
例えばこちらのプログラムをご覧ください。
num1 = 10
def setting():
num1 = 100
def plus():
num2 = 20
return num1 + num2
print(plus())
setting()
print(plus())
実行結果
30
30
最初にグローバル変数として「num1 = 10」を定義しています。
その後関数setting内で「num1 = 100」とグローバル変数num1を書き換えようと試みています。
そして関数plusが実行されると関数plus内で定義されたnum2と足し算され「120」と表示される…と予想されたのですが、実際は「30」と表示されました。
これは関数setting内で書き換えたと思っていた「num1 = 100」に問題があります。
関数内で「num1 = 100」と定義すると、これはその関数内でのローカル変数として定義されてしまいます。
つまり関数外で定義したグローバル変数は関数内からアクセスして値は取得できるものの、通常の代入では値を書き換えできないということです。
関数内でのグローバル変数の定義
関数内でグローバル変数にアクセスして値を書き換えるには、関数内でグローバル変数であることを定義する必要があります。
その場合は「global 変数名」を使い、その変数がグローバル変数であることを定義します。
num1 = 10
def setting():
global num1
num1 = 100
def plus():
num2 = 20
return num1 + num2
print(plus())
setting()
print(plus())
実行結果
30
120
関数内でグローバル変数を定義する場合、「global 変数名 = 値」という書き方はできないので注意してください。
num1 = 10
def setting():
global num1 = 100
def plus():
num2 = 20
return num1 + num2
print(plus())
setting()
print(plus())
実行結果
Input In [6]
global num1 = 100
^
SyntaxError: invalid syntax
また関数外でも「global 変数名」を使って変数がグローバル変数であることを明示することもできます。
global num1
num1 = 10
def setting():
global num1
num1 = 100
def plus():
num2 = 20
return num1 + num2
print(plus())
setting()
print(plus())
実行結果
30
120
今まで何となくで使っていたグローバル変数ですが、まとめてみるとなかなか奥が深いですし、値を取得するだけの時と書き換えるときで作法が違うことが結構印象的でした。
せっかく覚えたグローバル変数なので、次回はこのグローバル変数を使って、並列処理の同時終了を行ってみましょう。
ではでは今回はこんな感じで。
コメント