LoginSignup
0
1

More than 1 year has passed since last update.

pythonクロージャとnonlocal

Posted at

この記事

nonlocal ってどこに使うだろうって思ってたけど、ここだったのね、って話。

クロージャ作成例

# クロージャを用いた関数生成関数
def MakeFunc(a):
	""" a : 作成する関数に指定するパラメーター
	"""
	def Func(b):
		""" b : 作成された関数実行時の引数
		"""
		nonlocal a # バグ回避のためのおまじない
		return a*b

	return Func

# クロージャ使用
F2 = MakeFunc(2)
print(F2(3))

pythonでクロージャを使う場合の注意点

  • 関数内で代入が行われた変数は、global文またはnonlocal文で宣言が無い限り、その関数内のローカル変数となる
  • よって、上位関数のスコープにあり、クロージャに用いる変数は、上記の例のようにnonlocal文で宣言しておくことで、意図せずにバグを生じることが防げる。
  • nonlocal文で宣言することで、クロージャであることが明確になるので、不要な場合にもそうした方が良い。
    ※上記例ではnonlocal文が無くても問題無い

確認例

以下は、この辺の動作をJupyter上で確認したものです。

例1:バグで実行時エラーとなる書き方

In [1]
def MakeClosure(a):
    def Func(b):
        print(a)
        a = a + b
        print(a,b)
    return Func
In [2]
F1 = MakeClosure(1)
F1(2)
--------------------------------------------------------------------------
UnboundLocalError Traceback (most recent call last)
Input In [2], in <cell line: 2>()---> 1 F1(2)
Input In [1], in MakeClosure.<locals>.Func(b) 2 def Func(b):
---> 3 print(a) 4 a = a+ b 5 print(a,b)
UnboundLocalError: local variable 'a' referenced before assignment

例2:別の変数を用いて例1を修正

In [4]
def MakeClosure2(a):
    def Func(b):
        print(a)
        c = a+ b
        print(c,b)
    return Func
In [5]
G1 = MakeClosure2(1)
In [6]
G1(2)
1
3 2
In [7]
G9 = MakeClosure2(9)
In [8]
G9(2)
c
9
11 2

例3:globalを用いて例1を修正し、実行時エラー

In [9]
def MakeClosure3(a):
    def Func(b):
        global a
        print(a)
        a = a+ b
        print(a,b)
    return Func
In [10]
H1 = MakeClosure3(1)
In [11]
H1(2)
Traceback (most recent call last)
Input In [11], in <cell line: 1>()---> 1 H1(2)
Input In [9], in MakeClosure3.<locals>.Func(b) 2 def Func(b): 3 global a
---> 4 print(a) 5 a = a+ b 6 print(a,b)
NameError: name 'a' is not defined

例4:nonlocalを用いて例1を修正し

In [12]
def MakeClosure4(a):
    def Func(b):
        nonlocal a
        print(a)
        a = a+ b
        print(a,b)
    return Func
In [13]
I1 = MakeClosure4(1)
In [14]
I1(2)
1
3 2
0
1
0

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
1