python怎麼閉包 python的閉包

2021-10-11 13:01:56 字數 2968 閱讀 2452

一、思考乙個問題

我們要給定乙個x,要求一條直線上x對應的y的值。公式是y = kx+b。

我們需要用k,b來確定這條直線,則我們實現的函式應該有3個引數:

defline(k, b, x):print(k * x +b)

line(1, 3, 4)

line(1, 3, 5)

line(1, 3, 6)

可以看到,我們每次修改x都要重新傳入k和b。

我們也可以用全域性變數來實現:

k = 1b= 3

defline(x):print(k * x +b)

line(4)

line(5)

line(6)

k和b為全域性變數,但如果我們想要另外一條不同的直線時,則還需要重新定義k和b的值,同樣不合理。而且全域性變數會暴露給其他不相關的函式,容易造成衝突,或**混亂。

用物件導向來實現:

classline(object):def __init__(self, k, b):

self.k=k

self.b=bdefcreate_y(self, x):print(self.k * x +self.b)

l1= line(1, 3)

l1.create_y(4)

l1.create_y(5)

l1.create_y(6)

用類和物件來實現肯定是可以的,但是這麼乙個簡單的功能使用物件導向比較浪費資源。

二、使用閉包

defline(k, b):defcreate_y(x):print(k * x +b)returncreate_y

l1= line(1, 3)

l1(4)

l1(5)

l1(6)

從以上**可以直觀的看到,閉包有以下幾個條件:

1.在乙個外函式中定義了乙個內函式。

2.內函式裡運用了外函式的臨時變數。

3.並且外函式的返回值是內函式的引用。

乙個函式結束的時候,會把自己的臨時變數都釋放給記憶體,之後變數都不存在了。一般情況下,確實是這樣的。但是閉包是乙個特別的情況。外部函式發現,自己的臨時變數會在將來的內部函式中用到,自己在結束的時候,返回內函式的同時,會把外函式的臨時變數和內函式繫結在一起。所以外函式已經結束了,呼叫內函式的時候仍然能夠使用外函式的臨時變數。

三、內層函式修改外層函式臨時變數

defline(k, b):

multi= 10;defcreate_y(x):print((k * x + b) *multi)returncreate_y

l1= line(1, 3)

l1(4)

l1(5)

l1(6)

假設外層函式中有乙個multi變數,這個變數可以提供給內層函式訪問,但是如果內層函式想修改這個multi變數怎麼辦呢?

在python3.x中,我們可以使用nonlocal關鍵字來實現:

defline(k, b):

multi= 10;defcreate_y(x):

nonlocal multi

multi= 5

print((k * x + b) *multi)returncreate_y

l1= line(1, 3)

l1(4)

l1(5)

l1(6)

這個nonlocal類似與global的作用,但是global是用於修改全域性變數,而nonlocal是用於修改閉包中的外層臨時變數。

如果在python2.x中,則不存在nonlocal關鍵字,我們可以通過將multi變為可變型別資料來實現:

defline(k, b):#python2.x中將multi變為列表

multi = [10]defcreate_y(x):#可以對外層函式的列表進行修改

multi[0] = 5

print((k * x + b) *multi[0])returncreate_y

l1= line(1, 3)

l1(4)

l1(5)

l1(6)

四、閉包和函式、物件等的區別

函式(包含匿名函式):只是功能**,不包含資料。

物件:包含資料和功能實現。

閉包:包含資料和功能實現。資料指外層函式接收到的引數以及他的區域性變數,功能指內層函式的功能。

當函式、匿名函式、物件和閉包做為實參傳遞時,他們有什麼區別????

1.函式和匿名函式被當做實參傳遞時,傳遞的是功能的引用,可以通過該引用呼叫他們實現的功能。但資料需要另外提供。

2.閉包被當做實參傳遞時,其實傳遞了資料+功能。例如:

defline(k, b):#python2.x中將multi變為列表

multi = [10]defcreate_y(x):#可以對外層函式的列表進行修改

multi[0] = 5

print((k * x + b) *multi[0])returncreate_ydeffunction(func):

func(5)

function(line(1, 3))

我們可以看到,閉包line被傳入function,實際上帶著資料k=1,b=3。

而如果是普通函式:

defline_norm(k, b, x):print(k * x +b)deffunction(func):

func(1, 3, 5)

function(line_norm)

這裡的k=1,b=3是function函式自己提供的。

3.物件被當做實參傳遞時,該物件中的成員屬性作為資料,成員方法作為方法,都被傳遞給function函式。

classline(object):def __init__(self, k, b):

self.k=k

self.b=bdefcreate_y(self, x):print(self.k * x +self.b)

line1= line(1, 3)deffunction(inst):

inst.create_y(5)

function(line1)

python怎麼閉包 Python閉包

python閉包教程 閉包就是乙個 在閉包的記憶功能 在 python 中,獲到閉包中的變數讓閉包本身擁有了記憶效應,閉包中的邏輯可以修改閉包捕獲的變數,變數會跟隨閉包生命期一直存在,閉包本身就如同變數一樣擁有了記憶功能。python閉包定義詳解 語法def func param def func ...

python閉包怎麼理解 Python 閉包的理解

很多函式型的語言都有閉包這一概念,比如python的兄弟js。人們剛聽到閉包這一概念總會覺得它很晦澀,難以理解。其實不然,主要是他的名字起得太抽象了,讓人誤以為很難。下面舉乙個例子 coding utf 8 def foo nums 0 5 for i in range 5 nums i lambd...

python 閉包 python 閉包

閉包 因為python中函式也可以當作物件,所以如果出現當我們返回乙個函式,而該函式含有外部變數的時候就形成了閉包。閉包的特點 是個巢狀函式 可以獲得非區域性的變數 將函式當作物件返回 看乙個例子會更易理解 def make printer msg msg hi there def printer ...