作用域與帶有迴圈變數的預設引數相比較問題

2022-08-19 20:48:11 字數 1694 閱讀 8993

這個問題是來自於美國作家 魯特茲(mark lutz)所作的一本《learning python,fourth edition》書裡提及到的。

原文翻譯如下:

如果 lambda 或者 def 在函式中定義,巢狀在乙個迴圈之中,並且巢狀的函式引用了乙個上層作用域的變數,該變數被迴圈變數所改變,所有在這個迴圈變數中產生的函式將會有相同的值——在最後一次迴圈中完成時被引用變數的值。

>>> def makeactions():

... acts =

... for i in range(5):

... return acts

...

>>> acts = makeactions()

>>> acts[0](2)

16>>> acts[1](2)

16>>> acts[2](2)

16>>> acts[3](2)

16>>> acts[4](2)

16

批註:這個例子試圖在建立乙個函式的列表,其中每個函式都記住巢狀作用域中當前變數i的值。但是這並不怎麼有效:因為巢狀作用域中的變數在巢狀的函式被呼叫時才進行查詢,所以它們實際上記住的是同樣的值(在最後一次迴圈迭代中迴圈變數的值)。

我們來看下另乙個例子:

>>> def makeactions():

... acts =

... for i in range(5):

... return acts

...

>>> acts = makeactions()

>>> acts[0](2)

0>>> acts[1](2)

1>>> acts[2](2)

4>>> acts[3](2)

9>>> acts[4](2)

16

批註:這個是在巢狀作用域的值和預設引數方面遺留的一種仍需要解釋清楚的情況,而不是引用所在的巢狀作用域的值。為了實現你想要的效果,則必須使用預設引數把當前的值傳遞給巢狀作用域的變數。因為預設引數是在巢狀函式所建立**估的(而不是在其稍後呼叫時),每乙個函式記住了自己的變數i的值。

你也可以將上述**所定義的函式等價於:

>>> def makeactions():

... acts =

... for i in range(5):

... def func(x):

... return i ** x

... return acts

...

>>> def makeactions():

... acts =

... for i in range(5):

... def func(x, i = i):

... return i ** x

... return acts

...

批註:這是一種相當隱晦的情況,但是它會在實際情況中發生,特別是在生成應用於 gui 一些部件的**處理函式**中(例如,按鈕的事件處理)。

for迴圈中的變數作用域

for語句的語法如下 for expression1 expression2 expression3 statement expression1為初始化部分,它在迴圈裡只在開始時執行一次 expression2為條件部分,它在迴圈中每次都被執行。expression3 為調整部分,它在迴圈體每次執行...

python函式預設引數作用域

當def函式引數預設值為物件時,例如列表,字典 示例1 猜測一下,會輸出什麼?def ddd a,b return b print ddd 1 print ddd 2,a b c print ddd 3 1 a b c 2 3 你是否認為是這樣?輸出一下看看 輸出結果 1 a b c 2 1,3 看...

函式 引數 變數作用域

一 函式引數 1.必須引數 必需引數須以正確的順序傳入函式。呼叫時的數量必須和宣告時的一樣。呼叫printme 函式,你必須傳入乙個引數,不然會出現語法錯誤 小括號內的就是引數 小括號內沒東西叫做無參,有叫有參 求任意三個數之和 在定義函式的時候小括號內寫的是變數名字,不需要賦值 在呼叫函式的時候小...