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