python的閉包 3 0之前及之後

2021-08-25 01:22:47 字數 1519 閱讀 5884

首先, 說說python裡面的閉包吧:

1. 需要函式巢狀, 就是乙個函式裡面再寫乙個函式.

2. 外部函式需要返回乙個內部函式的引用

3. 外部函式中有一些區域性變數, 並且, 這些區域性變數在內部函式中有使用

概念:1. 自由變數: 外部函式中定義的區域性變數, 並且在內部函式中被使用.

2. 閉包: 那個使用了自由變數並被返回的內部函式就稱為閉包.

乙個例子:(來自def counter(start_at=0): count = [start_at] def incr(): count[0] += 1 return count[0] return incr

問題的提出: 關於python閉包的乙個問題, 呵呵, 論壇一位網友提出的問題: 自由變數只能是list嗎?

def f(): a = [1, 2] b = 1 c = 'hello' d = (1, ) e = true f = def inf(): print locals() a[0] += 1 b = 2 c = 3 d = (2, ) e = false f[1] = 3 return a[0] return inf a = f() t = a() print t

上面這一段**中, 內部函式inf第一句列印了locals(), 最終列印的結果只有a和f, 這段**我的測試環境是python2.5, windows平台...對於這段, 我總結:

1. 內部函式中, 遇到乙個變數, 如果是試圖改變它的子元素(集合型別)或自己命名空間(比如函式作為變數或物件作為變數時, 自己同時是命名空間)內部其他名稱的引用時, 將會合法的引用到外部變數.

2. 內部函式中, 遇到乙個變數, 如果試圖直接改變其自身, 多數情況都會得到"使用前未指定"的錯誤, 請看原因:

def f(): a = 1 def inf(): a += 1 return a return inf

最重要的就在a+=1這一句, 這裡, python實際上會認為你是在建立乙個新的本地變數並為他賦值, 也就是說, python的直譯器認為a+=1是a = a + 1, 而此時就很明顯了, 本地變數中目前沒有a, 所以, 就得到了我們上面說的那個錯誤...

3. 通常需要在閉包內部去修改外部函式變數的時候, 我們需要借助一些集合型別或有命名空間的物件進行操作.

以上這部分都是python3.0之前的情況, 在3.0之後, 加入了乙個新的關鍵字nonlocal, 就像當初的global關鍵字解決函式內修改全域性變數的問題一樣漂亮, nonlocal將閉包內修改外部變數的問題也很優美的搞定了.

def f(): a1 = 'hello' a2 = 1 a3 = o() a3.x = 1 def inf(): print(locals()) nonlocal a2, a1 a1 += ' world' a2 += 2 a3.x += 1 return a1, a2, a3 return inf

上面的**中, 通過在閉包內, 使用外部變數之前, 用nonlocal去宣告一下要在閉包中進行修改的那兩個變數不是本地變數, 就ok了, 和global的用法完全一致, 這樣, 我們就可以在其後的**段中, 修改普通的外部變數了.....

30 高階特性之閉包(2)

def calc sum args 可變引數 def inner sum ix 0 區域性變數,暫存累加結果 for y in args args是calc sum這個外部函式的變數,被內部函式inner sum使用了,故args為自由變數 ix y return ix return inner s...

python怎麼閉包 python的閉包

一 思考乙個問題 我們要給定乙個x,要求一條直線上x對應的y的值。公式是y kx b。我們需要用k,b來確定這條直線,則我們實現的函式應該有3個引數 defline k,b,x print k x b line 1,3,4 line 1,3,5 line 1,3,6 可以看到,我們每次修改x都要重新...

python 閉包 Python中的閉包

一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...