Python3中的閉包

1:閉包的定義

首先看下面代碼:

def outer():
	x = 100
	def inner():		
		print(x)
	return inner

ret = outer()
ret()

"""
輸出:
100
"""

在上面代碼中,對ret的調用本質上是運行了outer運行時,裏面創建的inner函數;這能行得通是因爲Python中函數和其他一切一樣都是對象,所以函數可以作爲其他函數的返回值傳遞回來。更重要的是裏面的函數inner記住了外層函數outer中的局部變量x,儘管外層函數outer已經不處於激活狀態。
這種代碼行爲我們稱之爲閉包,或者叫工廠函數。其特點是它能夠記住外層作用域中的值,不管那些嵌套作用域是否還在內存中。

其寫法爲:在外層函數中聲明一個變量. 在內層函數使用或者返回這個變量。

2:閉包的作用

a:記憶外層作用域中的值;
b:可以保護變量不被修改;
c:可以讓一個變量常駐內存;

def outer():
	x = 100
	def inner():
		print(x)
	return inner

# print(outer.x)  #  AttributeError: 'function' object has no attribute 'x'
outer.x = 300
print(outer.x)

action = outer()
action()

print(outer.x)


"""
輸出:
300
100
300

3:一簡單的工廠函數(閉包)

def outer(N):	
	def inner(X):
		return X**N
	return inner

f2 = outer(2)
print(f2(2))  # 2 ** 2
print(f2(3))  # 3 ** 2
print(f2(4))  # 4 ** 2

f3 = outer(3)
print(f3(2))  # 2 ** 3
print(f3(3))  # 3 ** 3
print(f3(4))  # 4 ** 3

4:使用 nonlocal 修改外層作用域中的變量

不能修改外層作用域中的變量(如下):

def outer(start):
	cnt = start
	def inner(lable):
		print(lable,cnt)
		# cnt += 1  # 不能修改外層作用域中的變量
	return inner


f1 = outer(10)
f1('f1')
f1('f1')

f2 = outer(10)
f2('f2')
f2('f2')

"""
f1 10
f1 10
f2 10
f2 10
"""

使用nonlocal :

def outer(start):
	cnt = start
	def inner(lable):
		nonlocal cnt
		print(lable,cnt)
		cnt += 1  
	return inner


f1 = outer(10)
f1('f1')
f1('f1')

f2 = outer(10)
f2('f2')
f2('f2')


f3 = outer(100)
f3('f3')
f3('f3')

f1('f1')
f2('f2')
f3('f3')

"""
# cnt 在f1,f2,f3中是獨立的
f1 10
f1 11
f2 10
f2 11
f3 100
f3 101
f1 12
f2 12
f3 102
"""

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章