主頁(yè) > 知識(shí)庫(kù) > 如何理解及使用Python閉包

如何理解及使用Python閉包

熱門標(biāo)簽:北瀚ai電銷機(jī)器人官網(wǎng)手機(jī)版 所得系統(tǒng)電梯怎樣主板設(shè)置外呼 朝陽(yáng)手機(jī)外呼系統(tǒng) 小蘇云呼電話機(jī)器人 地圖標(biāo)注面積 北京電銷外呼系統(tǒng)加盟 市場(chǎng)上的電銷機(jī)器人 儋州電話機(jī)器人 佛山400電話辦理

一、Python 中的作用域規(guī)則和嵌套函數(shù)

每當(dāng)執(zhí)行一個(gè)函數(shù)時(shí),就會(huì)創(chuàng)建一個(gè)新的局部命名空間,它表示包含函數(shù)體內(nèi)分配的函數(shù)參數(shù)和變量名的局部環(huán)境。我們可以將名稱空間看作一個(gè)字典,其中鍵是對(duì)象名稱,值是對(duì)象本身。

解析名稱時(shí),解釋器首先搜索本地命名空間。如果不存在匹配,則搜索全局名稱空間,該名稱空間是定義函數(shù)的模塊。如果仍然沒有找到匹配項(xiàng),則在引發(fā) NameError 異常之前最終檢查內(nèi)置名稱空間。下圖說(shuō)明了這一點(diǎn):

讓我們考慮下面的例子:

age = 27
def birthday(): 
  age = 28
birthday()
print(age)  # age will still be 27
>>
27

當(dāng)變量在函數(shù)內(nèi)部賦值時(shí),它們總是綁定到函數(shù)的本地名稱空間; 因此,函數(shù)體中的變量 age 指的是一個(gè)包含值28的全新對(duì)象,而不是外部變量??梢允褂萌终Z(yǔ)句更改此行為。下面的示例強(qiáng)調(diào)了這一點(diǎn):

age = 27
name = "Sarah"
def birthday(): 
  global age       # 'age' is in global namespace 
  age = 28
  name = "Roark"
birthday()         # age is now 28. name will still be "Sarah"

Python 也支持嵌套函數(shù)定義(函數(shù)內(nèi)部的函數(shù)):

def countdown(start):
  # This is the outer enclosing function
  def display():
    # This is the nested function
    n = start
    while n > 0:
      n-=1
      print('T-minus %d' % n)
 
  display()
# We execute the function
countdown(3)
>>>
T-minus 3
T-minus 2
T-minus 1

二、定義閉包函數(shù)

在上面的示例中,如果函數(shù) countdown()的最后一行返回了 display 函數(shù)而不是調(diào)用它,會(huì)發(fā)生什么情況?這意味著該函數(shù)的定義如下:

def countdown(start):
  # This is the outer enclosing function
  def display():
    # This is the nested function
    n = start
    while n > 0:
      n-=1
      print('T-minus %d' % n)
  return display
# Now let's try calling this function.
counter1 = countdown(2)
counter1()
>>>
T-minus 2
T-minus 1

使用值2調(diào)用 countdown()函數(shù),并將返回的函數(shù)綁定到名稱 counter1。在執(zhí)行 counter1()時(shí),它使用最初提供給 countdown ()的 start 值。因此,在調(diào)用 counter1()時(shí),盡管我們已經(jīng)執(zhí)行了 count1()函數(shù),但仍然記住這個(gè)值。

這種將一些數(shù)據(jù)(本例中為2)附加到代碼的技術(shù)在 Python 中稱為閉包。

即使變量超出范圍或函數(shù)本身從當(dāng)前名稱空間中移除,也會(huì)記住封閉范圍中的這個(gè)值。我們可以嘗試下面的代碼來(lái)確認(rèn):

>>> del countdown
>>> counter1()
T-minus 2
T-minus 1
>>> countdown(2)
Traceback (most recent call last):
...
NameError: name 'countdown' is not defined

三、何時(shí)使用閉包?

當(dāng)一個(gè)類中實(shí)現(xiàn)的方法很少(大多數(shù)情況下只有一個(gè)方法)時(shí),閉包可以提供一個(gè)替代的、更優(yōu)雅的解決方案。此外,如果我們希望根據(jù)延遲或延遲計(jì)算的概念編寫代碼,閉包和嵌套函數(shù)特別有用。下面是一個(gè)例子:

from urllib.request import urlopen
def page(url): 
  def get(): 
    return urlopen(url).read() 
  return get

在上面的示例中,page ()函數(shù)實(shí)際上并不執(zhí)行任何計(jì)算。相反,它只是創(chuàng)建并返回一個(gè)函數(shù) get () ,該函數(shù)在調(diào)用 web 頁(yè)面時(shí)獲取頁(yè)面內(nèi)容。因此,在 get ()中執(zhí)行的計(jì)算實(shí)際上被延遲到計(jì)算 get ()時(shí)程序中的某個(gè)后續(xù)點(diǎn)。例如:

>>> url1 = page("http://www.google.com") 
>>> url2 = page("http://www.bing.com") 
>>> url1
function page.locals>.get at 0x10a6054d0>
>>> url2
function page.locals>.get at 0x10a6055f0>
  
>>> gdata = url1()     # Fetches http://www.google.com 
>>> bdata = url2()     # Fetches http://www.bing.com
>>>

可以找到閉包函數(shù)中包含的值。

所有函數(shù)對(duì)象都有一個(gè) _closure_ 屬性,如果它是一個(gè)閉包函數(shù),那么這個(gè)屬性將返回一組單元格對(duì)象。根據(jù)上面的例子,我們知道 url1和 url2是閉包函數(shù)。

>>> page.__closure__       # Returns None since not a closure
>>> url1.__closure__
(cell at 0x10a5f1250: str object at 0x10a5f3120>,)

單元格對(duì)象具有存儲(chǔ)關(guān)閉值的屬性 cell_contents。

>>> url1.__closure__[0].cell_contents
'http://www.google.com'
>>> url2.__closure__[0].cell_contents
'http://www.bing.com'

四、總結(jié)

當(dāng)嵌套函數(shù)引用其封閉范圍中的值時(shí),可以定義 Python 中的閉包。閉包提供了某種形式的數(shù)據(jù)隱藏。閉包還可以是一種高效的方法,可以在一系列函數(shù)調(diào)用之間保持狀態(tài)。用 Python 創(chuàng)建一個(gè)閉包函數(shù):

  • 我們必須有一個(gè)嵌套的函數(shù)
  • 嵌套函數(shù)必須引用封閉函數(shù)中定義的值
  • 封閉函數(shù)必須返回嵌套函數(shù)

到此這篇關(guān)于如何理解及使用Python閉包的文章就介紹到這了,更多相關(guān)Python閉包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • python高級(jí)語(yǔ)法之閉包和裝飾器詳解
  • python閉包與引用以及需要注意的陷阱
  • 詳解python中的閉包
  • Python閉包及裝飾器運(yùn)行原理解析
  • Python閉包與裝飾器原理及實(shí)例解析
  • Python高級(jí)特性之閉包與裝飾器實(shí)例詳解
  • Python closure閉包解釋及其注意點(diǎn)詳解
  • 詳解python中的生成器、迭代器、閉包、裝飾器
  • Python閉包和裝飾器用法實(shí)例詳解
  • Python函數(shù)基礎(chǔ)實(shí)例詳解【函數(shù)嵌套,命名空間,函數(shù)對(duì)象,閉包函數(shù)等】

標(biāo)簽:定西 寧夏 商丘 酒泉 龍巖 金融催收 江蘇 云南

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《如何理解及使用Python閉包》,本文關(guān)鍵詞  如何,理解,及,使用,Python,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《如何理解及使用Python閉包》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于如何理解及使用Python閉包的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章