先來看乙個栗子:
def create():return [lambda x:i*x for i in range(5)]
for i in create():
print(i(2))
結果:
88888
create函式的返回值時乙個列表,列表的每乙個元素都是乙個函式 -- 將輸入引數x乘以乙個倍數i的函式。預期的結果時0,2,4,6,8. 但結果是5個8,意外不意外。
由於出現這個陷阱的時候經常使用了lambda,所以可能會認為是lambda的問題,但lambda表示不願意背這個鍋。問題的本質在與python中的屬性查詢規則,legb(local,enclousing,global,bulitin),在上面的例子中,i就是在閉包作用域(enclousing),而python的閉包是 遲繫結 , 這意味著閉包中用到的變數的值,是在內部函式被呼叫時查詢得到的
解決辦法也很簡單,那就是變閉包作用域為區域性作用域。
def create():return [lambda x, i=i:i*x for i in range(5)]
for i in create():
print(i(2))
換種寫法:
def create():a =
for i in range(5):
def demo(x, i=i):
return x*i
return a
for i in create():
print(i(2))
以上兩種寫法是一樣的
結果:
02468
再來乙個問題相似的栗子
**很簡單:(宣告:python3問題)
nums = range(2,20)for i in nums:
nums = filter(lambda x: x==i or x%i, nums)
print(list(nums))
結果:
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
同樣按照正常的邏輯結果應該為:
[2, 3, 5, 7, 11, 13, 17, 19]
問題產生的原因:
修改**:
nums = range(2,20)for i in nums:
nums = filter(lambda x,i=i: x==i or x%i, nums)
print(list(nums))
結果:
[2, 3, 5, 7, 11, 13, 17, 19]
更多python基礎教程---_<_>_----
更多python-re模組----_<_>_----
更多深入元類介紹----_<_>_----
linux--top命令詳解----_<_>_----
OC當中的閉包
oc當中閉包的基本定義 int sumblock int,int 隨後定義其具體的實現方式 int sumblock int,int int a,int b 關於swift 和oc中閉包的區別 可以看這個部落格 目前個人也不是很看得懂。隨後oc當中的閉包 是會捕獲外部的變數的,但不會對其進行修改,若...
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中的閉包
一 什麼是閉包 在談之前,我們先來說說作用域,變數的作用域無非就兩種 全域性變數和區域性變數。函式內部可以直接讀取全域性變數,但是在函式外部無法讀取函式內部的區域性變數。出於種種原因,我們有時候需要獲取到函式內部的區域性變數。但是,正常情況下,這是辦不到的!只有通過變通的方法才能實現。於是就引入了閉...