8. 函數-閉包
- 2019 年 10 月 3 日
- 筆記
一、函數名
函數名是⼀個變數, 但它是⼀個特殊的變數, 與括弧配合可以執⾏函數的變數。
1. 函數名的記憶體地址
def func(): print("呵呵") print(func) 結果: <function func at 0x1101e4ea0>
2. 函數名可以賦值給其他變數
def func(): print("呵呵") print(func) # 把函數當成⼀個變數賦值給另⼀個變數 a = func # 函數調⽤ func() a()
3. 函數名可以當做函數的參數
def func(): print("吃了么") def func2(fn): print("我是func2") fn() print("我是func2") # 把函數func當成參數傳遞給func2的參數fn. func2(func)
4. 函數名可以作為函數的返回值
def func_1(): print("這⾥是函數1") def func_2(): print("這⾥是函數2") print("這⾥是函數1") return func_2 # 執⾏函數1. 函數1返回的是函數2, 這時fn指向的就是上⾯函數2 fn = func_1() # 執⾏上⾯返回的函數 fn()
二、閉包
1. 定義
如果在一個內部函數里,對在外部作用於(但不是在全局作用域)的變數進行引用,那麼內部函數就被認為是閉包。
閉包(Closure)是詞法閉包(Lexical Closure)的簡稱,是引用了自由變數的函數。這個被引用的自由變數將和這個函數一同存在,即使已經離開了創造它的環境也不例外。所以,閉包是由函數和與其相關的引用環境組合而成的實體。
通俗的講就是:如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變數進行引用,那麼內部函數就被認為是閉包(closure)。它只不過是個「內層」的函數,由一個名字(變數)來指代,而這個名字(變數)對於「外層」包含它的函數而言,是本地變數。
閉包的主要用途:實現裝飾器
2. 閉包運用
- 閉包函數必須有內嵌函數
- 內嵌函數需要引用該嵌套函數上一級namespace中的變數
- 閉包函數必須返回內嵌函數
(1) 普通閉包
def func(a, b): def line(x): return a * x - b return line line = func(2, 3) print(line(5))
(2) 修改值閉包
def func(a, b): def line(x): nonlocal a a = 3 return a * x - b return line line = func(2, 3) print(line(5))