閉包:巢狀定義在非全域性作用域裡面的函式,能夠記住它被定義時所處的封閉命名空間;
在乙個函式內容定義乙個函式,在內部的函式可以攜帶外部函式的資訊;這樣可以使得函式的組合運用更加的靈活;
我們看乙個例子:
def line_conf(a, b):
# 在函式內部定義了乙個函式
def line(x):
return a*x+b # 返回值是乙個值
return line #返回值是乙個函式
# 測試一下,我們發現這個line_conf可以包裝出很多新的函式
line1 = line_conf(1,1) # 1*x+1
print(line1) #.line at 0x000002a784e1f400>
print(line1(5)) # 6
line2 = line_conf(4,5) # 4*x+5
print(line2) # .line at 0x000002a784e25400>
print(line2(5)) # 25
這便是python函式的閉包特性,使得python的函式功能非常強大!
我們再來看乙個例子,進一步來說明python 閉包的強大及其帶來的python另乙個重要的特性:裝飾器。
# 用物件導向來寫乙個簡單的座標處理類
class coordinate(object):
def __init__(self, x, y):# 構造方法
self.x = x
self.y = y
def __repr__(self): # 列印方法,當print時,以一定的格式輸出
return "x: " + str(self.x) + ", y: "+ str(self.y)
def add(a, b):
return coordinate(a.x+b.x, a.y+b.y)
def sub(a, b):
return coordinate(a.x-b.x, a.y-b.y)
# 測試一下**
one = coordinate(100,200)
two = coordinate(300,200)
print(add(one, two)) # 400, 400
print(sub(one, two)) # -200, 0
這很好理解。
但是,隨著新的需求產生,我們可能需要將原來的函式進一步的擴充和增強。
比如上面的例子,來了新的需求:要求其座標不能小於0,否則需要置0;
面對這樣的問題怎麼辦?我們來看下解決方案:
# 用物件導向來寫乙個簡單的座標處理類
class coordinate(object):
def __init__(self, x, y):# 構造方法
self.x = x
self.y = y
def __repr__(self): # 列印方法,當print時,以一定的格式輸出
return "x: " + str(self.x) + ", y: "+ str(self.y)
# 新的需求:座標不能小於0,否則需要置0
#!!!用乙個閉包來擴充原函式的邏輯!!!
def sub(a, b):
return coordinate(a.x-b.x, a.y-b.y)
one = coordinate(100,200)
two = coordinate(300,200)
print(add(one, two)) # 400, 400
print(sub(one, two)) # 0, 0 # 這裡的座標置0
#寫**時,比較好的模式是:可以擴充,但是不要更改已經寫好的邏輯!
注意:這個例子中原有的**沒有改變,而功能得以增強。這就是python中的裝飾器,
而也正是我們後面要提的物件導向設計模式中裝飾器模式的一種python實現。
在下一節中,我們可以看一下,在沒有語言機制支援時,如何來實現這種設計模式。
python 閉包函式 python函式物件和閉包
一 函式物件 函式物件指的是函式可以被當做 資料 來處理,具體可以分為四個方面的使用,我們如下 1.1 函式可以被引用 def add x,y return x y func add func 1,2 1.2 函式可以作為容器型別的元素 dic dicdic add 1.3 函式可以作為引數傳入另外...
python中物件導向程式設計閉包
什麼是閉包?閉包指的是乙個擁有許多變數和繫結了這些變數的環境的表示式,通常是乙個函式,因而這些變數也是該表示式的一部分,閉包一詞 於要執行的 塊和為自由變數提供繫結的計算環境兩者的結合 在乙個外部函式中的乙個內部函式,內部函式運用了外部函式的臨時變數,並且外部函式返回值是內部函式的引用,這樣就構成乙...
Python 函式物件與閉包
函式物件指的是函式可以被當做 資料 來處理,具體可以分為四個方面的使用。def index print from index a index a def foo x,y,func print x,y func def bar print from bar foo 1,2,bar 1 2 from b...