閉包
內(nèi)部函數(shù)調(diào)用外部函數(shù)的變量(一個閉包就是你調(diào)用的一個函數(shù)A,這個函數(shù)A返回一個函數(shù)B給你扳缕。這個返回的函數(shù)B就叫做閉包)
優(yōu)點:可以提高代碼的可復(fù)用性慌闭,減少了代碼的可移植性
特點:一個獨立的空間,多個閉包互補影響躯舔,占用空間遠(yuǎn)小于實例對象驴剔;
注意點:引用了外部函數(shù)的局部變量,則外部函數(shù)的局部變量沒有及時釋放粥庄,消耗內(nèi)存
nonlocal 修改一個函數(shù)內(nèi)部變量時使用
# 定義一個函數(shù)
def test(number):
# 在函數(shù)內(nèi)部再定義一個函數(shù)丧失,并且這個函數(shù)用到了外邊函數(shù)的變量,那么將這個函數(shù)及用到的一些變量稱之為閉包
def test_in(number_in):
print("in text_in 函數(shù), number_in is %d" % number_in)
return number + number_in
# 其實這里返回的就是閉包的結(jié)果
return text_in
# 給test函數(shù)賦值惜互,這個20就是給參數(shù)number
ret = test(20)
# 注意這里的100其實給參數(shù)的number_in
print(ret(100))
# 注意這里的200其實給參數(shù)number_in
print(ret(200))
運行結(jié)果:
in test_in 函數(shù), number_in is 100
120
in test_in 函數(shù), number_in is 200
220
裝飾器
定義一個函數(shù)布讹,在運行時動態(tài)增加功能
在不修改原函數(shù)的代碼的情況下琳拭,添加新的功能,可以在執(zhí)行原函數(shù)之前加描验,也可以在執(zhí)行原函數(shù)之后添加
-
注意點:
- 裝飾器只能在調(diào)用原函數(shù)之前或之后添加功能白嘁,而不能在函數(shù)的中間添加功能
- 只要用裝飾器裝飾了的函數(shù),那么不管被調(diào)用多少次挠乳,都是裝飾之后的效果
裝飾器(decorator)功能
1.引入日志
2.函數(shù)執(zhí)行時間統(tǒng)計
3.執(zhí)行函數(shù)前預(yù)備處理
4.執(zhí)行函數(shù)后清理功能
5.權(quán)限校驗等場景
6.緩存
#### 第一波 ####
def foo()
print("foo")
foo # 表示是函數(shù)
foo() # 表示執(zhí)行foo函數(shù)
#### 第二波 ####
def foo()
print("foo")
foo = lambda x: x + 1
foo() # 執(zhí)行l(wèi)ambda表達(dá)式权薯, 而不再是原來的foo函數(shù), 因為foo這個名字被重新指向另外一個匿名函數(shù)
寫代碼要遵循開放封閉原則睡扬,它規(guī)定已經(jīng)實現(xiàn)的功能代碼不允許被修改盟蚣,但可以被擴(kuò)展
- 封閉:對實現(xiàn)功能的代碼塊
- 開放:擴(kuò)展開發(fā)一般情況下為了讓裝飾器更通用,可以有return
裝飾的時候:誰離被裝飾的函數(shù)越近卖怜,那么就先裝誰
調(diào)用的時候:誰離的遠(yuǎn)屎开,那么先調(diào)誰