python 變數作用域問題(經典坑)

2021-08-22 04:30:49 字數 1378 閱讀 7214

偶爾看到python的乙個經典坑:

flist =

[lambda

:i for i in

range(5

)]for f in flist():

print

(f()

)

按照一般邏輯,結果應該是 0 1 2 3 4

但執行結果是

444

44

查了一下,主要是變數作用域問題和函式執行的問題。

出現這種情況的主要原因是,迴圈在python中不形成作用域。也就是說,i不僅僅在for迴圈內有效,for迴圈結束後i依然可以被使用,即迴圈結束後,i=4

比如說,如果這樣寫:

flist = [lambda :i for i in range(5)]

del i

flist[0]()

就會報錯

nameerror                                 traceback (most recent call last)

in ()

1 flist = [lambda :i for i in range(5)]

----> 2 del i

3 flist[0]()

nameerror: name 'i' is not defined

因為把i刪除了之後,lambda就沒辦法找到返回值i了。

然後,只有函式在被呼叫的時候才執行函式內部的東西,也就是說,在遍歷flist的時候,每呼叫乙個f,lambda :i 被執行一次,但記住這時候i=4,所以所有f都返回4。

要想達到預期效果,可以稍微修改一下:

flist =

[lambda x=i: x for i in

range(5

)]for f in flist:

print

(f()

)

輸出結果

012

34

為什麼這樣就可以了呢?先看下面:

flist=

for i in

range(5

):deffunc()

: x = i

return x

flist[0]

()

輸出結果是0。這段**和上面是等價的。可以看到,i 的值此時被傳遞進了函式,也就是說,每乙個 func 中都有 i值。等到迴圈結束,flist中的函式元素被呼叫的時候,因為 i 值在迴圈的時候已經成了每個func函式中的區域性變數,也就是0 1 2 3 4,所以flist0=0。

python的變數作用域問題

偶然掉進了乙個坑里。仔細分析了下原因。原來是變數作用域的問題。簡單抽象如下 id 1 許多行 id for id in range 10 許多行 if id 1 做一些事情 pass else 做另外一些事情 結果由於id在 id for id in range 10 中受到了影響發生了變化,導致蟲...

變數作用域問題

2018 04 09 首先一定要明白乙個問題,那就是你py程式裡面的變數作用域問題。因為你程式是工作在乙個分布式機器上的,那麼這些個資料就會分布在不同的機器上,或者說container上。要明確spark的工作架構,各個不同的工作身份。那麼乙個變數他是不是在不同的機器執行,他是不是最後會彙總到我們的...

python變數作用域

變數作用域 scope 在python中是乙個容易掉坑的地方。什麼是作用域 作用域簡單說就是乙個變數的命名空間。中變數被賦值的位置,就決定了哪些範圍的物件可以訪問這個變數,這個範圍就是命名空間。python賦值時生成了變數名,當然作用域也包括在內。python的作用域一共有4中,分別是 l loca...