posts - 403, comments - 310, trackbacks - 0, articles - 7
            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

          Python中inner function的binding處理

          Posted on 2008-10-17 20:06 ZelluX 閱讀(509) 評論(0)  編輯  收藏 所屬分類: OOP
          BBS上的一個帖子,問題是
          def?a():
          ????
          def?b():
          ????????x?
          +=?1
          ?
          ????x?
          =?1
          ????
          print?"a:?",?x
          ????b()
          ????
          print?"b:?",?x
          ?
          def?c():
          ????
          def?d():
          ????????x[0]?
          =?[4]
          ????x?
          =?[3]
          ????
          print?"c:?",?x[0]
          ????d()
          ????
          print?"d:?",?x[0]

          運行a()會報UnboundLocalError: local variable ‘x’ referenced before assignment
          但是運行c()會正確地顯示3和4。

          原因在于原因在于CPython實現closure的方式和常見的functional language不同,采用了flat closures實現。

          “If a name is bound anywhere within a code block, all uses of the name within the block are treated as references to the current block.”

          在第一個例子中,b函數x += 1對x進行賦值,rebind了這個對象,于是Python查找x的時候只會在local environment中搜索,于是就有了UnboundLocalError。

          換句話說,如果沒有修改這個值,比如b中僅僅簡單的輸出了x,程序是可以正常運行的,因為此時搜索的范圍是nearest enclosing function region。

          而d方法并沒有rebind x變量,只是修改了x指向的對象的值而已。如果把賦值語句改成x = [4],那么結果就和原來不一樣了,因為此時發生了x的rebind。

          所以Python中的closure可以理解為是只讀的。

          另外第二個例子也是這篇文章中提到的一種workaround:把要通過inner function修改的變量包裝到數組里,然后在inner function中訪問這個數組。

          至于為什么Python中enclosed function不能修改enclosing function的binding,文中提到了主要原因還是在于Guido反對這么做。因為這樣會導致本應該作為類的實例保存的對象被聲明了本地變量。

          參考網站:http://www.python.org/dev/peps/pep-0227/


          主站蜘蛛池模板: 永德县| 拜城县| 富宁县| 伊川县| 年辖:市辖区| 信宜市| 镇远县| 阿图什市| 抚顺市| 奈曼旗| 定襄县| 襄垣县| 格尔木市| 西青区| 东方市| 长丰县| 吴桥县| 泸水县| 灯塔市| 康乐县| 鄄城县| 安新县| 武宣县| 方山县| 万载县| 宽甸| 盖州市| 樟树市| 上林县| 陕西省| 论坛| 九龙城区| 伊川县| 樟树市| 龙口市| 丹阳市| 玉山县| 乌海市| 宜君县| 台前县| 辽源市|