一般來說閉包這個概念在很多語言中都有涉及,本文主要談談python中的閉包定義及相關用法。Python中使用閉包主要是在進行函數式開發時使用。詳情分析如下:
一、定義
python中的閉包從表現形式上定義(解釋)為:如果在一個內部函數里,對在外部作用域(但不是在全局作用域)的變量進行引用,那么內部函數就被認為是閉包(closure).這個定義是相對直白的,好理解的,不像其他定義那樣學究味道十足(那些學究味道重的解釋,在對一個名詞的解釋過程中又充滿了一堆讓人抓狂的其他陌生名詞,不適合初學者)。下面舉一個簡單的例子來說明。
>>>def addx(x): >>> def adder(y): return x + y >>> return adder >>> c = addx(8) >>> type(c) <type 'function'> >>> c.__name__ 'adder' >>> c(10) 18
結合這段簡單的代碼和定義來說明閉包:
如果在一個內部函數里:adder(y)就是這個內部函數,
對在外部作用域(但不是在全局作用域)的變量進行引用:x就是被引用的變量,x在外部作用域addx里面,但不在全局作用域里,
則這個內部函數adder就是一個閉包。
再稍微講究一點的解釋是,閉包=函數塊+定義函數時的環境,adder就是函數塊,x就是環境,當然這個環境可以有很多,不止一個簡單的x。
二、使用閉包注意事項
1.閉包中是不能修改外部作用域的局部變量的
>>> def foo(): ... m = 0 ... def foo1(): ... m = 1 ... print m ... ... print m ... foo1() ... print m ...>>> foo()010
從執行結果可以看出,雖然在閉包里面也定義了一個變量m,但是其不會改變外部函數中的局部變量m。
2.以下這段代碼是在python中使用閉包時一段經典的錯誤代碼
def foo(): a = 1 def bar(): a = a + 1 return a return bar
這段程序的本意是要通過在每次調用閉包函數時都對變量a進行遞增的操作。但在實際使用時
>>> c = foo() >>> print c() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in bar UnboundLocalError: local variable 'a' referenced before assignment
這是因為在執行代碼 c = foo()時,python會導入全部的閉包函數體bar()來分析其的局部變量,python規則指定所有在賦值語句左面的變量都是局部變量,則在閉包bar()中,變量a在賦值符號"="的左面,被python認為是bar()中的局部變量。再接下來執行print c()時,程序運行至a = a + 1時,因為先前已經把a歸為bar()中的局部變量,所以python會在bar()中去找在賦值語句右面的a的值,結果找不到,就會報錯。解決的方法很簡單
新聞熱點
疑難解答