老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

python中的閉包函數有哪些-創新互聯

本篇文章給大家分享的是有關python中的閉包函數有哪些,小編覺得挺實用的,因此分享給大家學習,希望大家閱讀完這篇文章后可以有所收獲,話不多說,跟著小編一起來看看吧。

阿里地區ssl適用于網站、小程序/APP、API接口等需要進行數據傳輸應用場景,ssl證書未來市場廣闊!成為創新互聯公司的ssl證書銷售渠道,可以享受市場價格4-6折優惠!如果有意向歡迎電話聯系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

閉包函數初探

通常我們定義函數都是這樣定義的

def foo():
 pass

其實在函數式編程中,函數里面還可以嵌套函數,如下面這樣

def foo():
 print("hello world in foo")
 
 def bar():
 print("hello world in bar")

此時我們調用foo函數,執行結果會是什么樣子的呢??

hello world in foo

結果如上所示,只會執行foo函數的第一層函數,bar函數是不會被執行的。為什么呢

實際上來說,不管函數寫在哪個部分,那都只是定義了一個函數,只有這個函數被調用,函數內部的語句才會被執行

在上面的例子中,bar函數雖然在foo函數內部定義了,但是并沒有被執行,所以bar函數是不會被執行的這樣說來,定義在一個函數內部的函數就沒什么作用了嗎??其實不是這樣的。

來看下面的例子,把bar函數作為一個值返回給foo函數,來看執行過程

def foo():
 print("hello world in foo")
 
 def bar():
 print("hello world in bar")
 return bar
f1=foo()
print(f1)

此時,由于bar函數作為一個返回值被返回給了foo,所以foo函數執行結果是有返回值的

此時定義一個變量f1來接收foo函數的執行返回結果,然后打印f1

返回的結果如下

hello world in foo
.bar at 0x0000000002941A60>

可以看到首先打印了foo函數中定義的一個print語句,接著打印的是foo函數中包含的bar函數的內存地址

既然是一個函數的內存地址,當然可以加括號來執行這個函數

def foo():
 print("hello world in foo")
 def bar():
 print("hello world in bar")
 return bar
f1=foo()
f1()

此時,這段代碼的執行結果為:

hello world in foo
hello world in bar

兩個print語句都被打印出來了。

在上面的例子里,首先定義了一個函數foo,接著在foo函數內部又嵌套定義了一個函數bar,然后返回函數bar的函數名,這就是閉包函數的定義方式。

其實,閉包的定義就是一個函數內部又嵌套了一個函數

來看下面的這段代碼

 def foo():
 print("hello world in foo")
 name="python"
 def bar():
  print(name)
  print("hello world in bar")
 return bar
 
 f1=foo()
 f1()

在上面的例子里,在外層函數中定義了一個變量name,然后在內層函數中打印這個變量name

此時執行上面的代碼,在打印name這個變量的時候,會先在bar函數內部查找name這個變量,但是bar函數里面是沒有name這個變量的,

此時根據python查找變量的LEGB法則,會到bar函數的外面一層去繼續查找name這個變量,此時可以找到name這個變量

所以這里打印的foo函數中定義的name的值

執行上面的代碼,打印結果如下

hello world in foo
python
hello world in bar

這里要記住很重要的一點就是:

內層函數引用了外層函數的局部變量

來分析下上面的例子中程序的執行過程:

首先運行foo函數,foo函數的執行結果是返回bar的函數名,此時又把foo函數的執行結果定義給了變量f1,
所以此時f1就等于bar這個函數的內存地址,然后f1加括號運行就表示運行了bar函數。
在執行bar函數的過程中,bar函數訪問到了外層foo函數中定義的變量,這就是一個典型的閉包函數
那使用閉包函數有什么好處呢??在上面的例子里,f1的值是bar函數的內存地址,f1加括號運行就是在運行bar函數。

又由于f1是一個全局變量,這意味著可以在整個程序的任意位置都可以運行f1函數,此時再定義一個函數,在這個函數內部調用f1函數,

 def foo():
 print("hello world in foo")
 name = "python"
 
 def bar():
  print(name)
  print("hello world in bar")
 return bar
 
 f1 = foo()
 
 def func():
 name = "aaaaa"
 f1()
 func()

來分析一下程序的執行過程:

1.運行func函數,程序會先在內存中申請一塊空間以保存name變量的值,然后運行f1函數,f1是在全局中定義的變量,所以一定可以找到f1函數的內存地址

2.f1加括號運行,就是在執行一個閉包函數,這個閉包函數內部引用了name這個變量

3.name這個變量在bar函數的外部已經定義了,所以在func函數內部調用f1函數,也就是bar函數時,其引用的變量依然是foo函數內部定義的name變量,而不是func函數內部定義的name變量,

4.因為f1函數的內部已經包含了name這個函數的值,所以就算在func函數內部也定義了name這個變量,程序執行的結果打印的依然是foo函數內部定義的name的值

程序執行結果

hello world in foo
python
hello world in bar

怎樣驗證一個函數是閉包函數

首先,閉包函數都有一個特有的屬性:closure

在上面的例子里,打印f1的__closure__屬性  

 def foo():
 name = "python"
 def bar():
  print(name)
  print("hello world in bar")
 return bar
 f1 = foo()
 print(f1.__closure__)

打印結果如下:

(,)

可以看到__closure__屬性的打印結果是一個元組形式的,其值就是f1函數的外層函數作用域

此時可以調用__closure__返回的元組的元素的cell_contents方法打印出name變量的值

 def foo():
 name = "python"
 
 def bar():
  print(name)
  print("hello world in bar")
 return bar
 
 f1 = foo()
 print(f1.__closure__[0].cell_contents)

打印結果如下:

python

可以看到程序已經打印出name變量的值了

即然__closure__的返回結果是一個元組,那么這個元組中一定是可以包含多個值的,看下面的例子

在foo函數內部定義多個變量,然后在bar函數內部打印幾個變量的值,

然后運行這個閉包函數,打印閉包函數的__closure__方法   

 def foo():
 print("hello world in foo")
 name1 = "python1"
 name2 = "python2"
 name3 = "python3"
 name4 = "python4" 
 def bar():
  print(name1)
  print(name2)
  print(name3)
  print(name4)
  print("hello world in bar")
 return bar 
 f1 = foo()
 print(f1.__closure__)

程序執行結果

()

由于在foo函數內部定義了4個變量,而且在bar函數內部引用了這4個變量,所以打印這個閉包函數的__closure__方法,返回的元組中就有4個元素

現在可以分別打印返回的元組中的這4個字符串對象的值了   

 def foo():
 name1 = "python1"
 name2 = "python2"
 name3 = "python3"
 name4 = "python4"
 
 def bar():
  print(name1)
  print(name2)
  print(name3)
  print(name4)
  print("hello world in bar")
 return bar 
 f1 = foo()
 print(f1.__closure__[0].cell_contents)
 print(f1.__closure__[1].cell_contents)
 print(f1.__closure__[2].cell_contents)
 print(f1.__closure__[3].cell_contents)

程序執行結果

python1
python2
python3
python4

那么現在還剩下最后一個問題了,那就是閉包函數的內層函數一定要返回嗎??

來看下面一個例子

 def foo():
 name = "python1" 
 def bar():
  print(name)
 print(bar.__closure__) 
 foo()

定義了一個嵌套函數,然后這個嵌套函數的內層函數沒有被返回,而是直接打印內層函數的__closure__方法,然后直接調用外層函數。

程序執行結果

(,)

依然打印出了內層函數的引用的變量對象

這說明閉包函數的內層函數還一定要返回

閉包函數的內層函數可以調用全局變量嗎??

把外層函數內部定義的變量改為全局變量,然后在內層函數中引用這個變量

 name = "python1"
 def foo():
 def bar():
  print(name) 
 print(bar.__closure__)
 f=foo()
 print(f)

程序執行結果

None
None

可以看到,程序的執行結果是兩個None,嵌套函數的內層函數的__closure__函數的值為None

這說明foo函數的內層嵌套函數bar調用的全局變量沒有成功,所以上面的例子不是一個閉包函數

關于閉包函數的一些總結:

閉包的定義為:

    在函數內部定義的函數,稱為內部函數
    內部函數調用了外部函數的局部變量
    即使內部函數返回了,還是可以使用局部變量
    通常閉包函數的內層函數都要被返回給外部函數
    閉包函數的外部函數可以在任何地方被調用,而不再受函數定義時層級的限制

閉包函數的作用

1.閉包函數自帶函數作用域

正常意義上的函數,在函數執行過程中查找變量的順序是一層一層向外找,符合LEGB(Local->Enclose->Global->Built in)法則的,

但是對閉包函數來說,查找變量只會找內部函數外面的那一層,因為閉包函數本身就自帶一層作用域,這樣才符合"閉包"兩個字的意思

2.延遲計算(也叫惰性計算)

看下面的例子

 def func():
 name="python"
 def bar():
  print(name)
 return bar 
 f=func()
 print(f.__closure)

在上面的例子里,執行foo()函數的返回結果是一個包含自帶的某種狀態的函數,實際上這個函數并沒有執行,

以后想執行這個自帶狀態的函數時,把func()返回結果所賦值的那個變量加括號就可以執行了,

3.要想讓一個函數始終保持一種狀態,就可以使用閉包

例子:

 name="python" 
 def func():
 print("I like %s" % name) 
 func()

上面的代碼執行結果會打印一行:"I like python"

但是我們知道,在不同的地方調用func函數,打印的結果很大可能是不一樣的

那么如果我想不管在什么地方調用func函數,打印的結果都是"I like python"時,

就可以使用閉包了。

 def func1(): 
 name="python"
 def func():
  print("I like %s" % name)
 return func
 func=func1()
 func()

如上圖所示,在func函數外面再包含一層函數func1,執行func1函數,再把func1函數的返回結果賦值給func這個變量

此時func就是一個閉包函數了,把func函數加括號就可以執行了

以上就是python中的閉包函數有哪些,小編相信有部分知識點可能是我們日常工作會見到或用到的。希望你能通過這篇文章學到更多知識。更多詳情敬請關注創新互聯成都網站設計公司行業資訊頻道。

另外有需要云服務器可以了解下創新互聯scvps.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業上云的綜合解決方案,具有“安全穩定、簡單易用、服務可用性高、性價比高”等特點與優勢,專為企業上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


當前標題:python中的閉包函數有哪些-創新互聯
網頁網址:http://www.xueling.net.cn/article/ddooed.html

其他資訊

在線咨詢
服務熱線
服務熱線:028-86922220
TOP
主站蜘蛛池模板: 日韩中文毛片在线 | japan21xxxxhd日本妞 | 国产91亚洲精品 | 色综合久久久久综合一本到桃花网 | 免费看国产美女裸体视频 | 少妇性荡欲视频午夜剧场 | 丰满少妇a片免费观看 | yy6969久久亚洲精品 | 男女视频91| 人与人一级毛片 | 欧美三级不卡在线观看 | 亚洲男同帅GAY片在线观看 | 欧美成人亚洲成人 | 一级毛片中文字幕 | 亚洲精品四区 | 福利一区二区视频 | 免费看一级黄色 | 91在线精品一区二区三区 | 九九久久免费视频 | 国产性网 | 午夜大尺度福利视频 | 久久久久女人精品毛片 | 成人午夜高潮a∨猛片 | 激情国产AV做激情国产爱 | 欧美性猛交xxxx乱大交少妇 | 菠萝蜜在线免费观看 | 欧美阿v高清资源在线 | 蜜臀AV免费一区二区三区 | 国产精品96久久久久久吹潮 | 亚洲视频网站在线 | 99蜜久久精品国产首页 | 久久无码色综合中文字幕 | 国产成a人亚洲精v品久久网 | 在线观看av大片 | 激情春色| 国产精品久久艹 | 黄色片免费看视频 | 四虎影视精品成人 | 误杀2国语版免费观看 | 国产美女特级嫩嫩嫩bbb片 | 无码人妻一区二区三区一 |