<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      Python深入04 閉包

      作者:Vamei 出處:http://www.rzrgm.cn/vamei 歡迎轉載,也請保留這段聲明。謝謝!

       

      閉包(closure)是函數式編程的重要的語法結構。函數式編程是一種編程范式 (而面向過程編程和面向對象編程也都是編程范式)。在面向過程編程中,我們見到過函數(function);在面向對象編程中,我們見過對象(object)。函數和對象的根本目的是以某種邏輯方式組織代碼,并提高代碼的可重復使用性(reusability)。閉包也是一種組織代碼的結構,它同樣提高了代碼的可重復使用性。

      不同的語言實現閉包的方式不同。Python以函數對象為基礎,為閉包這一語法結構提供支持的 (我們在特殊方法與多范式中,已經多次看到Python使用對象來實現一些特殊的語法)。Python一切皆對象,函數這一語法結構也是一個對象。在函數對象中,我們像使用一個普通對象一樣使用函數對象,比如更改函數對象的名字,或者將函數對象作為參數進行傳遞。

       

      函數對象的作用域

      和其他對象一樣,函數對象也有其存活的范圍,也就是函數對象的作用域。函數對象是使用def語句定義的,函數對象的作用域與def所在的層級相同。比如下面代碼,我們在line_conf函數的隸屬范圍內定義的函數line,就只能在line_conf的隸屬范圍內調用。

      def line_conf():
          def line(x):
              return 2*x+1
          print(line(5))   # within the scope
      
      
      line_conf()
      print(line(5))       # out of the scope

      line函數定義了一條直線(y = 2x + 1)。可以看到,在line_conf()中可以調用line函數,而在作用域之外調用line將會有下面的錯誤:

      NameError: name 'line' is not defined

      說明這時已經在作用域之外。

       

      同樣,如果使用lambda定義函數,那么函數對象的作用域與lambda所在的層級相同。

       

      閉包

      函數是一個對象,所以可以作為某個函數的返回結果

      def line_conf():
          def line(x):
              return 2*x+1
          return line       # return a function object
      
      my_line = line_conf()
      print(my_line(5))       

      上面的代碼可以成功運行。line_conf的返回結果被賦給line對象。上面的代碼將打印11。

       

      如果line()的定義中引用了外部的變量,會發生什么呢?

      def line_conf():
          b = 15
          def line(x):
              return 2*x+b
          return line       # return a function object
      
      b = 5
      my_line
      = line_conf() print(my_line(5))

      我們可以看到,line定義的隸屬程序塊中引用了高層級的變量b,但b信息存在于line的定義之外 (b的定義并不在line的隸屬程序塊中)。我們稱b為line的環境變量。事實上,line作為line_conf的返回值時,line中已經包括b的取值(盡管b并不隸屬于line)。

      上面的代碼將打印25,也就是說,line所參照的b值是函數對象定義時可供參考的b值,而不是使用時的b值。

       

      一個函數和它的環境變量合在一起,就構成了一個閉包(closure)。在Python中,所謂的閉包是一個包含有環境變量取值的函數對象。環境變量取值被保存在函數對象的__closure__屬性中。比如下面的代碼:

      def line_conf():
          b = 15
          def line(x):
              return 2*x+b
          return line       # return a function object
      
      b = 5
      my_line = line_conf()
      print(my_line.__closure__)
      print(my_line.__closure__[0].cell_contents)

      __closure__里包含了一個元組(tuple)。這個元組中的每個元素是cell類型的對象。我們看到第一個cell包含的就是整數15,也就是我們創建閉包時的環境變量b的取值。

       

      下面看一個閉包的實際例子:

      def line_conf(a, b):
          def line(x):
              return a*x + b
          return line
      
      line1 = line_conf(1, 1)
      line2 = line_conf(4, 5)
      print(line1(5), line2(5))

      這個例子中,函數line與環境變量a,b構成閉包。在創建閉包的時候,我們通過line_conf的參數a,b說明了這兩個環境變量的取值,這樣,我們就確定了函數的最終形式(y = x + 1和y = 4x + 5)。我們只需要變換參數a,b,就可以獲得不同的直線表達函數。由此,我們可以看到,閉包也具有提高代碼可復用性的作用。

      如果沒有閉包,我們需要每次創建直線函數的時候同時說明a,b,x。這樣,我們就需要更多的參數傳遞,也減少了代碼的可移植性。利用閉包,我們實際上創建了泛函。line函數定義一種廣泛意義的函數。這個函數的一些方面已經確定(必須是直線),但另一些方面(比如a和b參數待定)。隨后,我們根據line_conf傳遞來的參數,通過閉包的形式,將最終函數確定下來。

       

      閉包與并行運算

      閉包有效的減少了函數所需定義的參數數目。這對于并行運算來說有重要的意義。在并行運算的環境下,我們可以讓每臺電腦負責一個函數,然后將一臺電腦的輸出和下一臺電腦的輸入串聯起來。最終,我們像流水線一樣工作,從串聯的電腦集群一端輸入數據,從另一端輸出數據。這樣的情境最適合只有一個參數輸入的函數。閉包就可以實現這一目的。

      并行運算正稱為一個熱點。這也是函數式編程又熱起來的一個重要原因。函數式編程早在1950年代就已經存在,但應用并不廣泛。然而,我們上面描述的流水線式的工作并行集群過程,正適合函數式編程。由于函數式編程這一天然優勢,越來越多的語言也開始加入對函數式編程范式的支持。

       

      歡迎繼續閱讀“Python快速教程

       

       

      posted @ 2012-12-15 00:27  Vamei  閱讀(51394)  評論(32)    收藏  舉報
      主站蜘蛛池模板: 国产一区二区高清不卡| 亚洲精品中文字幕二区| 九九热在线视频观看最新| 欧美综合自拍亚洲综合图| 色综合久久中文综合久久激情 | 欧美黑人大战白嫩在线| 亚洲欧美日韩在线码| 日本一区二区三区东京热| 瑞丽市| 亚洲中文一区二区av| 欧美日本在线一区二区三区| 久久精品国产色蜜蜜麻豆| 国产AV福利第一精品| 亚洲一区二区中文字幕| 亚洲狼人久久伊人久久伊| 利辛县| 久久精品国产91久久麻豆| 亚洲乱亚洲乱妇50p| 激情亚洲内射一区二区三区| 国产 另类 在线 欧美日韩| 国产毛片精品av一区二区| 亚洲日韩久热中文字幕| 免费黄色大全一区二区三区| 老司机免费的精品视频| 亚洲中文字幕日韩精品| 国产激情国产精品久久源| 在线视频精品中文无码| 999福利激情视频| 亚洲精品久久一区二区三区四区| AI做受???高潮AAAA视频| 亚洲精品理论电影在线观看| 亚洲日本va午夜中文字幕久久 | 国产成人一区二区三区视频免费| 亚洲精品熟女一区二区| 精品视频不卡免费观看| 精品国产中文字幕第一页| 日韩激情无码免费毛片| 日韩免费美熟女中文av| 狠狠色丁香婷婷久久综合五月| 国产熟睡乱子伦视频在线播放| 久久香蕉国产线看观看猫咪av|