<dl id="vorq8"><menu id="vorq8"></menu></dl>

<sup id="vorq8"></sup>
<sup id="vorq8"></sup>
<sup id="vorq8"></sup>

<optgroup id="vorq8"><address id="vorq8"></address></optgroup>

    <sup id="vorq8"><menu id="vorq8"><small id="vorq8"></small></menu></sup>

    <div id="vorq8"><tr id="vorq8"><object id="vorq8"></object></tr></div>

    當前位置:  首頁  >  PHP教程  >  PHP 應用  >  常見問題

    Python編程中運用閉包時所需要注意的一些地方

    這篇文章主要介紹了Python編程中運用閉包時所需要注意的一些地方,文章來自國內知名的Python開發者felinx的博客,需要的朋友可以參考下
    寫下這篇博客,起源于Tornado郵件群組的這個問題how to use outer variable in inner method,這里面老外的回答很有參考價值,關鍵點基本都說到了。我在這里用一些有趣的例子來做些解析,簡要的闡述下Python的閉包規則,首先看一個經典的例子:

    def foo():
     a = 1
     def bar():
      a = a + 1
      # print a + 1
      # b = a + 1
      # a = 1
      print id(a)
     
     bar()
     print a, id(a)
    
    

    在Python2.x上運行這個函數會報UnboundLocalError: local variable 'a' referenced before assignment即本地變量在引用前未定義,如何來理解這個錯誤呢?PEP 227里面介紹到,Python解析器在搜索一個變量的定義時是根據如下三級規則來查找的:

    The Python 2.0 definition specifies exactly three namespaces to check for each name — the local namespace, the global namespace, and the builtin namespace.

    這里的local實際上可能還有多級,上面的代碼就是一個例子,下面通過對代碼做些簡單的修改來一步步理解這里面的規律:

    • 如果將a = a + 1這句換成print a + 1或者b = a + 1,是不會有問題的,即在內部函數bar內,外部函數foo里的a實際是可見的,可以引用。
    • 將a = a + 1換成 a = 1也是沒有問題的,但是如果你將兩處出現的a的id打印出來你會發現,其實這兩個a不是一回事,在內部函數bar里面,本地的a = 1定義了在bar函數范圍內的新的一個局部變量,因為名字和外部函數foo里面的變量a名字相同,導致外部函數foo里的a在內部函數bar里實際已不可見。
    • 再來說a = a + 1出錯是怎么回事,首先a = xxx這種形式,Python解析器認為要在內部函數bar內創建一個新的局部變量a,同時外部函數foo里的a在bar里已不可見,而解析器對接下來對右邊的a + 1的解析就是用本地的變量a加1,而這時左邊的a即本地的變量a還沒有創建(等右邊賦值呢),因此就這就產生了一個是雞生蛋還是蛋生雞的問題,導致了上面說的UnboundLocalError的錯誤。

    要解決這個問題,在Python2.x里主要有兩個方案:

    用別名替代比如b = a + 1,內部函數bar內只引用外部函數foo里的a。
    將foo里的a設成一個容器,如list

     def foo():
      a = [1, ]
      def bar():
       a[0] = a[0] + 1
      
      bar()
      print a[0]
    

    當然這有些時候還是很不方便,因此在Python3.x中引入了一個nonloacal的關鍵字來解決這個問題,只要在a = a + 1前加一句nonloacal a即可,即顯式的指定a不是內部函數bar內的本地變量,這樣就可以在bar內正常的使用和再賦值外部函數foo內的變量a了。

    在搜索Python閉包相關的材料中,我在StackOverflow上發現一個有趣的有關Python閉包的問題,有興趣的可以思考思考做做看,結果應該是什么?你預期的結果是什么,若不一致,如果要得到你預期的結果應該怎么改?

    flist = []
     
    for i in xrange(3):
     def func(x): return x * i
     flist.append(func)
     
    for f in flist:
     print f(2)
    
    
    吐了個 "CAO" !
    掃碼關注 PHP1 官方微信號
    PHP1.CN | 中國最專業的PHP中文社區 | PHP資訊 | PHP教程 | 數據庫技術 | 服務器技術 | 前端開發技術 | PHP框架 | 開發工具 | PHP問答
    Copyright ? 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社區 版權所有
         
    pc蛋蛋
    <dl id="vorq8"><menu id="vorq8"></menu></dl>

    <sup id="vorq8"></sup>
    <sup id="vorq8"></sup>
    <sup id="vorq8"></sup>

    <optgroup id="vorq8"><address id="vorq8"></address></optgroup>

      <sup id="vorq8"><menu id="vorq8"><small id="vorq8"></small></menu></sup>

      <div id="vorq8"><tr id="vorq8"><object id="vorq8"></object></tr></div>

      <dl id="vorq8"><menu id="vorq8"></menu></dl>

      <sup id="vorq8"></sup>
      <sup id="vorq8"></sup>
      <sup id="vorq8"></sup>

      <optgroup id="vorq8"><address id="vorq8"></address></optgroup>

        <sup id="vorq8"><menu id="vorq8"><small id="vorq8"></small></menu></sup>

        <div id="vorq8"><tr id="vorq8"><object id="vorq8"></object></tr></div>