首頁 >後端開發 >Python教學 >為什麼我的巢狀函數只能存取其父函數中局部變數的最終值?

為什麼我的巢狀函數只能存取其父函數中局部變數的最終值?

Barbara Streisand
Barbara Streisand原創
2024-12-16 12:49:14475瀏覽

Why Does My Nested Function Only Access the Final Value of a Local Variable in Its Parent Function?

巢狀函數中的局部變數

巢狀函數提供了一種在父函數中封裝特定函數的便利方法。然而,它們的閉包行為可能會在局部變數的可訪問性和值方面引入一些複雜性。

問題:

考慮以下程式碼片段:

from functools import partial

class Cage(object):
    def __init__(self, animal):
        self.animal = animal

def gotimes(do_the_petting):
    do_the_petting()

def get_petters():
    for animal in ['cow', 'dog', 'cat']:
        cage = Cage(animal)

        def pet_function():
            print("Mary pets the " + cage.animal + ".")

        yield (animal, partial(gotimes, pet_function))

funs = list(get_petters())

for name, f in funs:
    print(name + ":", f())

期望的行為是每次迭代打印三種不同的動物(「牛」、「狗」、「貓」)。但是,該程式僅在所有迭代中列印“cat”。這種行為與局部變數籠子與巢狀函數關聯的預期相矛盾。

答案:

誤解在於巢狀函數儲存引用的假設定義時其父作用域的局部變數。實際上,巢狀函數僅在執行時才從父作用域尋找變數。

在這個特定範例中,為 pet_function 建立的閉包從 get_petters 函數中索引了 cage 變數。當 pet_function 被呼叫時,它會存取閉包以檢索 cage 的值。然而,此時 get_petters 函數已完成,籠變數的最終值為「cat」。因此,對任何 pet_function 變體的所有後續呼叫都會傳回值「cat」。

解決方法:

要解決此問題,可以使用各種技術來確保巢狀函數存取cage的正確值:

  • 部分函數: 利用functools.partial 建立一個具有固定值的新函數。
  • 作用域函數: 在迴圈中建立一個新函數,以確保每個函數都有唯一的作用域pet_function 的實例。
  • 預設參數值: 將籠子作為預設參數值傳遞給pet_function.

透過採用其中一種方法,您可以確保巢狀函數在每次迭代時訪問預期的局部變數。

以上是為什麼我的巢狀函數只能存取其父函數中局部變數的最終值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn