在Python中,閉包是一個非常重要的概念,它可以讓我們很方便地實現一些緩存,裝飾器等功能。而變量作為一個基本的概念,也與閉包密不可分。
閉包的主要特點是可以讓函數捕捉封閉作用域的狀態,并將其保存起來,然后在函數的生命周期內進行訪問和修改。這就要求閉包中的變量是必須要有一個作用域來改變和訪問。
在Python中,我們使用關鍵字“nonlocal”來修飾閉包中的變量,表示對外部作用域中的變量進行引用和修改。
def outer(): x = 0 def inner(): nonlocal x x += 1 print(x) return inner f = outer() f() # 輸出1 f() # 輸出2 f() # 輸出3
在上面的代碼中,我們定義了一個外層函數outer,它返回了一個內層函數inner。在inner中我們引用了外層函數outer中的變量x,并將其加1。在外層函數outer中,x的初始值是0。
我們再來看一個例子:
def outer(): x = 0 def inner(): y = 1 nonlocal x x += y print(x) return inner f = outer() f() # 輸出1 f() # 輸出2 f() # 輸出3
在這個例子中,我們除了引用了外部作用域的變量x之外,還定義了一個內層作用域的變量y。注意到這里的y是不會被閉包存儲的,因為它不在閉包的作用域范圍之內。
在Python中,閉包的變量會通過__closure__這個屬性存儲在函數對象中。我們可以通過下面的代碼來查看一個函數對象中保存的閉包變量:
def outer(): x = 0 def inner(): nonlocal x x += 1 print(x) print(inner.__closure__) return inner f = outer()
在上面的代碼中,我們使用了print(inner.__closure__)來查看inner中保存的閉包變量,輸出結果為(x, )。這個元組中只有一個元素,就是閉包變量x所在的cell。
最后,需要注意的是,在Python中,閉包中的變量是通過引用來訪問和修改的,它們并不是獨立的對象。因此,在進行復雜的操作時,需要特別小心,防止意外修改了閉包變量的值。