Python基础之闭包
Python基礎(chǔ)之閉包
一.閉包的定義:
在一個(gè)函數(shù)的內(nèi)部,再定義一個(gè)函數(shù)(內(nèi)部函數(shù))。這個(gè)內(nèi)部函數(shù)引用了外部函數(shù)的變量,并且外部函數(shù)返回這個(gè)內(nèi)部函數(shù),我們把這個(gè)使用外部函數(shù)變量的內(nèi)部函數(shù)稱為閉包 。
簡而言之,閉包就是能夠讀取外部函數(shù)內(nèi)的變量的函數(shù)。
例如:
def f1(): # f1外部函數(shù) n = 999 # n:外部函數(shù)的變量 def f2(): # 內(nèi)部函數(shù) print(n) # f2中引用f1的變量 return f2 # 外部函數(shù)f1返回內(nèi)部函數(shù)f2,函數(shù)f2即是閉包#調(diào)用法一f1()()# 調(diào)用法二# result=f1()# result()形成閉包的兩個(gè)條件:
- 函數(shù)的返回值必須是被包函數(shù)對(duì)象(函數(shù)名)
- 閉包中必須引用了外層函數(shù)作用域內(nèi)的變量或者形參
二.閉包的用途
①可以讀取函數(shù)內(nèi)部的變量
②將一些變量的值始終保存到內(nèi)存中
1.讀取函數(shù)內(nèi)部的變量
在一般情況下 ,在函數(shù)外部我們是不能訪問到函數(shù)內(nèi)部的變量的。但是,有時(shí)想要在函數(shù)外部能夠訪問到函數(shù)內(nèi)部的變量 ,那么就可以使用閉包。
例如:
def f1(): a=100print(a) #NameError: name 'a' is not defined上面的代碼可以看出 ,print(a)會(huì)拋異常NameError: name 'a' is not defined。在函數(shù)f1的外面無法訪問它的變量的。
在函數(shù)f1里面定義一個(gè)閉包函數(shù)就可以訪問到了
例如:
def f1(): a = 100 def f2(): return a return f2result = f1()a = result()print(a)2.將一些變量的值始終保存到內(nèi)存中
def f1(n1): # 外部函數(shù) def f2(n2): # 內(nèi)部函數(shù) result = n1 + n2 # 內(nèi)部函數(shù)引用了外部函數(shù)的變量n1 print('計(jì)算結(jié)果:', result) return f2f=f1(1) #創(chuàng)建閉包實(shí)例#執(zhí)行閉包f(2)f(3)運(yùn)行結(jié)果:
計(jì)算結(jié)果: 3計(jì)算結(jié)果: 4通過上面的輸出結(jié)果可以看出閉包保存了外部函數(shù)內(nèi)的變量n1的值1 ,每次執(zhí)行閉包都是在n1 = 1 基礎(chǔ)上進(jìn)行計(jì)算的。
三.閉包的缺點(diǎn)
1.由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,會(huì)增加內(nèi)存消耗,所以不能濫用閉包,否則會(huì)造成程序的性能問題 ,可能導(dǎo)致內(nèi)存泄露
2.閉包無法改變外部函數(shù)局部變量指向的內(nèi)存地址
3.返回閉包時(shí),返回函數(shù)不要引用任何循環(huán)變量,或者后續(xù)會(huì)發(fā)生變化的變量
四.判斷一個(gè)函數(shù)是否是閉包
判斷一個(gè)函數(shù)是不是閉包,可以查看它的closure屬性。如果該函數(shù)是閉包,查看該屬性將會(huì)返回一個(gè)cell對(duì)象組成的tuple。如果我們分別對(duì)每個(gè)cell對(duì)象查看其cell_contents屬性 ,返回的內(nèi)容就是閉包引用的自由變量的值。
def outer(args): a = 10 b = 15 c = 25 def inner(): return a + b+args return innerout = outer(4) # 閉包實(shí)例print(out.__closure__)運(yùn)行結(jié)果:
( , , | ) | | | 閉包的__closure__方法 ,可以展示出閉包儲(chǔ)存了外部函數(shù)的兩個(gè)變量,cell的內(nèi)存地址是什么 ,在cell里面儲(chǔ)存的對(duì)象類型是int ,這個(gè)int儲(chǔ)存的內(nèi)存地址是什么。
閉包的__closure__方法 ,可以查看每個(gè)cell對(duì)象的內(nèi)容
def outer(args): a = 10 b = 15 c = 25 def inner(): return a +b+ args return innerout = outer(4) # 閉包實(shí)例# print(out.__closure__)for i in out.__closure__: print(i.cell_contents)運(yùn)行結(jié)果:
10415cell_contents解釋了局部變量在脫離函數(shù)后仍然可以在函數(shù)之外被訪問的原因 ,因?yàn)樽兞勘淮鎯?chǔ)在cell_contents中了 。
展開閱讀全文投稿時(shí)間