1. 程式人生 > >8. 函式-閉包

8. 函式-閉包

一、函式名

​ 函式名是⼀個變數, 但它是⼀個特殊的變數, 與括號配合可以執⾏函式的變數。

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))