0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonのglobalキーワードを省略できるケース

Last updated at Posted at 2022-06-16

Pythonのglobal変数

短いスクリプトを書いたり、サンプルコードを少し実験してみるときには、私はしっかり作り込んだりせずglobal変数に頼ったりすることが多いです。そういったシーンでは、global変数を参照する際に毎回globalキーワードを記述するのも面倒。省略できるなら省略したい。けどどんなときに省略できるのか詳しくわかっていませんでした。
いくつか実験をしてみましたのでみなさんの参考になればと思います。

まずはわかった結論から

  • globalキーワードを省略すると?
    • defの中など、あるローカル名前空間でglobalキーワードを省略した場合、書き換えが行われる変数が、グローバル変数と同じ名称だった場合、それはグローバル変数ではなく、新しいローカル変数であると判断されるようです。そして一旦ローカルであると判断されたあとはその名前空間では絶対に同一名称のグローバル変数へのアクセスができなくなるようです。
    • 一方で、書き換えを行わないのであればglobalキーワードを省略してもグローバル変数として扱われるようです。ややこしい。誰だこんなヘンテコルール作ったやつ。
  • 覚えておくこと
    • 開発の流れの中では、まずはグローバル変数を参照する記述をすることが多いのではないかと思います。そのときはglobalキーワードは必要ありません。
    • いざ、その変数を書き換えたくなった瞬間!globalキーワードを書いてください。
      • 忘れた場合、グローバル変数を参照していたそれまでのコードが、一転してローカル変数への参照となります
      • 1ヶ所書き換えただけなのに、その前から周辺が動かなくなるなんてことも十分あり得ます。
      • この法則は覚えておく必要があります。
glb = 30
def func(arg):
	lcl = glb * glb # グローバル変数を参照する記述 ok!
	return lcl

 ↓

glb = 30
def func(arg):
	if arg == False:
		glb = 0 # 新規記述。グローバル変数を書き換えようとした。
	lcl = glb * glb # もうグローバル変数を参照していない。
	return lcl

実際のコードで確認

#!python3
glb = 30
ret = None

def func0():
	return glb # これはglobalを参照している

def func1():
	glb = 5 # これはlocal変数
	return glb

def func2():
	global glb # これはglobalを参照している
	glb = 5
	return glb

def func3():
	lcl = glb # これはglobalを参照している
	return lcl

def func4():
	glb = glb # エラー。これはlocal変数。不定値参照。
	return glb

def func5():
	glb = 5 # これはlocal変数
	#global glb # エラー。local変数と同一名称のglobal変数
	glb = 5
	return glb

def reset():
	global glb
	global ret
	glb = 30
	ret = None


reset()
print(f"after reset :   ret:{ret}, glb:{glb}")

reset()
ret = func0()
print(f"after func0 :   ret:{ret}, glb:{glb}")

reset()
ret = func1()
print(f"after func1 :   ret:{ret}, glb:{glb}")

reset()
ret = func2()
print(f"after func2 :   ret:{ret}, glb:{glb}")

reset()
ret = func3()
print(f"after func3 :   ret:{ret}, glb:{glb}")

reset()
ret = func4()
print(f"after func4 :   ret:{ret}, glb:{glb}")

reset()
ret = func5()
print(f"after func5 :   ret:{ret}, glb:{glb}")

結果

after reset :   ret:None, glb:30
after func0 :   ret:30, glb:30
after func1 :   ret:5, glb:30
after func2 :   ret:5, glb:5
after func3 :   ret:30, glb:30
Traceback (most recent call last):
  File "/Users/shinya.ohtani/Documents/CodeRunner documents/Sample.py", line 52, in <module>
    ret = func4()
  File "/Users/shinya.ohtani/Documents/CodeRunner documents/Sample.py", line 29, in func4
    glb = glb # エラー。これはlocal変数。不定値参照。
UnboundLocalError: local variable 'glb' referenced before assignment

参考

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?