我目前正在學習 Python 指標,但無法理解它們。假設您有一個創建其他函式的函式,如下所示:
def create_function(data):
def new_function(other_data):
if data.member == 0:
other_data.member = 1
return new_function
test_func = create_function(object)
這將如何作業,因為函式指標只能在 create_function() 的范圍內訪問資料?它只能在包含函式的背景關系中呼叫,還是函式物件保留對此資料的參考?
uj5u.com熱心網友回復:
該函式保留對此資料的參考。(這種事情,一個帶有“捕獲”變數的函式通常稱為閉包)。
從語言參考的函式定義部分:
程式員須知:函式是一流的物件。在函式定義中執行的“def”陳述句定義了一個可以回傳或傳遞的區域函式。嵌套函式中使用的自由變數可以訪問包含 def 的函式的區域變數。有關詳細資訊,請參閱命名和系結部分。
uj5u.com熱心網友回復:
python 將按照本地、封閉、全域和最終內置的順序查找名稱。在這種情況下new_function,包含在 中create_function,因此new_function會data在 中找到create_function。
uj5u.com熱心網友回復:
閉包是在封閉范圍內記住值的函式物件。
- 它以封閉的環境存盤功能。
- 閉包——與普通函式不同——允許函式通過閉包的值或參考的副本訪問這些捕獲的變數,即使函式在其作用域之外被呼叫。
uj5u.com熱心網友回復:
我假設您來自 C 背景,因為您提到了函式指標。
在 C 中,函式可以訪問作用域內的所有變數。這通常包括在其中宣告的區域變數以及指定函式接收的任何引數。更巧妙的是,它還包括在最外層作用域中宣告的全域變數。全域變數最接近這里發生的情況。即使函式在函式之外,函式也可以訪問它們。
在 C 中,所有全域變數的地址在編譯期間都是已知的。當函式訪問這個變數時,它使用這個地址。它是靜態的。此外,無法在運行時創建新函式或變數。編譯器觀察到的變數不能改變。
在支持閉包的動態語言中,函式和變數是動態創建的。您可以撰寫代碼來為您生成新函式。您可以擁有一個函式,該函式接受指定新函式的行為方式的引數,然后為您生成并回傳它。就好像您的 C 程式中嵌入了一個 C 編譯器,可以動態生成新函式。
為了支持這些強大的功能,函式必須存盤對作用域內所有變數的參考,就像 C 編譯器在內部所做的那樣。因此,雖然在 C 中編譯函式幾乎可以由一個簡單的函式指標完全描述,但在 Python 中,函式是具有指向將要運行的代碼的指標以及指向它們創建時作用域中所有變數的指標的物件。
創建函式時,我們說變數已被捕獲。這些變數如何改變取決于它們的作用域和誰有權訪問它們。請注意,函式作用域在回傳時結束。如果沒有其他函式捕獲這些變數,則不會再次參考它們。
讓我們分解一個例子:
z = 0
def f(x):
def g(y):
return x y z
return g
f(1)(2)
這是這段代碼中發生的事情:
z是全域或檔案范圍內的變數。它對它下面的所有東西都是可見的。
f當執行到達此行時定義。它捕獲
z變數。z全域更改將改變函式的行為方式。這是可能的,因為其他代碼z由于其全域范圍也可以訪問。x此時不系結。它只有在呼叫函式時才有價值。g在f呼叫時定義。它還捕獲
z.由于
x現在已系結到一個值,因此它也捕獲了該值。即使它是一個每次f呼叫都會改變的區域變數,也會發生這種情況。的每個新實體都g將存盤對x傳遞給f創建它的呼叫的參考。每次都可以是不同的值。y只有在g被呼叫時才有價值。f用1作為引數呼叫。這將創建并回傳一個
g參考 globalz和 local的新函式x。由于
f完成執行并回傳,因此包含的范圍x變得不可訪問。g現在是唯一參考此x變數的范圍。它永遠不能在該范圍之外進行更改。g回傳并使用2作為引數呼叫新的。最后,計算結果。
z指的是一個全域變數。x指f創建 this的特定呼叫中的引數g。y是函式的引數。他們下定決心,
0 1 2結果是3。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/326393.html
上一篇:使用列中的起始值計算數值Pandas(python)
下一篇:在r資料框中查找資料集中的佇列
