一般來說閉包這個(gè)概念在很多語言中都有涉及,本文主要談?wù)刾ython中的閉包定義及相關(guān)用法。Python中使用閉包主要是在進(jìn)行函數(shù)式開發(fā)時(shí)使用。詳情分析如下:
一、定義
python中的閉包從表現(xiàn)形式上定義(解釋)為:如果在一個(gè)內(nèi)部函數(shù)里,對(duì)在外部作用域(但不是在全局作用域)的變量進(jìn)行引用,那么內(nèi)部函數(shù)就被認(rèn)為是閉包(closure).這個(gè)定義是相對(duì)直白的,好理解的,不像其他定義那樣學(xué)究味道十足(那些學(xué)究味道重的解釋,在對(duì)一個(gè)名詞的解釋過程中又充滿了一堆讓人抓狂的其他陌生名詞,不適合初學(xué)者)。下面舉一個(gè)簡(jiǎn)單的例子來說明。
>>>def addx(x): >>> def adder(y): return x + y >>> return adder >>> c = addx(8) >>> type(c) <type 'function'> >>> c.__name__ 'adder' >>> c(10) 18
結(jié)合這段簡(jiǎn)單的代碼和定義來說明閉包:
如果在一個(gè)內(nèi)部函數(shù)里:adder(y)就是這個(gè)內(nèi)部函數(shù),
對(duì)在外部作用域(但不是在全局作用域)的變量進(jìn)行引用:x就是被引用的變量,x在外部作用域addx里面,但不在全局作用域里,
則這個(gè)內(nèi)部函數(shù)adder就是一個(gè)閉包。
再稍微講究一點(diǎn)的解釋是,閉包=函數(shù)塊+定義函數(shù)時(shí)的環(huán)境,adder就是函數(shù)塊,x就是環(huán)境,當(dāng)然這個(gè)環(huán)境可以有很多,不止一個(gè)簡(jiǎn)單的x。
二、使用閉包注意事項(xiàng)
1.閉包中是不能修改外部作用域的局部變量的
>>> def foo(): ... m = 0 ... def foo1(): ... m = 1 ... print m ... ... print m ... foo1() ... print m ...>>> foo()010
從執(zhí)行結(jié)果可以看出,雖然在閉包里面也定義了一個(gè)變量m,但是其不會(huì)改變外部函數(shù)中的局部變量m。
2.以下這段代碼是在python中使用閉包時(shí)一段經(jīng)典的錯(cuò)誤代碼
def foo(): a = 1 def bar(): a = a + 1 return a return bar
這段程序的本意是要通過在每次調(diào)用閉包函數(shù)時(shí)都對(duì)變量a進(jìn)行遞增的操作。但在實(shí)際使用時(shí)
>>> 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
這是因?yàn)樵趫?zhí)行代碼 c = foo()時(shí),python會(huì)導(dǎo)入全部的閉包函數(shù)體bar()來分析其的局部變量,python規(guī)則指定所有在賦值語句左面的變量都是局部變量,則在閉包bar()中,變量a在賦值符號(hào)"="的左面,被python認(rèn)為是bar()中的局部變量。再接下來執(zhí)行print c()時(shí),程序運(yùn)行至a = a + 1時(shí),因?yàn)橄惹耙呀?jīng)把a(bǔ)歸為bar()中的局部變量,所以python會(huì)在bar()中去找在賦值語句右面的a的值,結(jié)果找不到,就會(huì)報(bào)錯(cuò)。解決的方法很簡(jiǎn)單
新聞熱點(diǎn)
疑難解答
圖片精選