目錄
- 一、閉包
- 1. 什么是閉包?
- 2. 形成閉包的三個條件(缺一不可)
- 3. 閉包的原理
- 4. 閉包的好處
- 二、裝飾器
- 1. 什么是裝飾器
- 2. 裝飾器有什么用
- 3. 小 練 習
- 三. 編寫和使用裝飾器
- 1. 小案例
- 2.應用注意事項
- 3.保留元數(shù)據(jù)-什么是元數(shù)據(jù)
- 4.保留元數(shù)據(jù)-裝飾器后為什么元數(shù)據(jù)會丟失
- 5.保留元數(shù)據(jù)
- 6.小案例
- 7.內置的裝飾器
- 四. 裝飾器的應用
- 五. 課后作業(yè)
- 1.實現(xiàn)函數(shù)注冊表
- 2.完善三創(chuàng)購物系統(tǒng)
- 總結
一、閉包
1. 什么是閉包?
在函數(shù)中可以(嵌套)定義另一個函數(shù)時,如果內部的函數(shù)引用了外部的函數(shù)的變量,則可能產(chǎn)生 閉包。
閉包可以用來在一個函數(shù)與一組“私有”變量之間創(chuàng)建關聯(lián)關系。
在給定函數(shù)被多次調用的過程中,這些私有變量能夠保持其持久性。
2. 形成閉包的三個條件(缺一不可)
必須有一個內嵌函數(shù)(函數(shù)里定義的函數(shù))——這對應函數(shù)之間的嵌套
內嵌函數(shù)必須引用一個定義在閉合范圍內(外部函數(shù)里)的變量——內部函數(shù)引用外部變量
外部函數(shù)必須返回內嵌函數(shù)——必須返回那個內部函數(shù)
換句話說:
其實,閉包的概念很簡單:一個可以引用在函數(shù)閉合范圍內變量的函數(shù)。即"內部函數(shù)",只有那個內部函 數(shù)才有所謂的__closure__屬性。
3. 閉包的原理
形成閉包之后,閉包函數(shù)會獲得一個非空的__closure__屬性(對比我們最后的函數(shù)test,test是一 個不具備閉包的函數(shù),它的__closure__屬性是None),這個屬性是一個元組。
組里面的對象為cell對象,而訪問cell對象的cell_contents屬性則可以得到閉包變量的當前值 (即上一次調用之后的值)。
而隨著閉包的繼續(xù)調用,變量會再次更新。
所以可見,一旦形成閉包之后,python確實會將__closure__和閉包函數(shù)綁定作為儲存閉包變量的場所
4. 閉包的好處
閉包不是必須的。
沒了閉包,python的功能一點不會被影響
有了閉包,只是提供給你一種額外的解決方案。
二、裝飾器
1. 什么是裝飾器
飾器是這樣一種設計模式:如果一個類(函數(shù))希望添加其他類(函數(shù))的一些功能,而不希望 通過繼承或是直接修改源代碼實現(xiàn),那么可以使用裝飾器模式。
簡單來說Python中的裝飾器就是指某些函數(shù)或其他可調用對象,以函數(shù)或類作為可選輸入?yún)?shù), 然后返回函數(shù)或類的形式。通過這個在Python2.6版本中被新加入的特性可以用來實現(xiàn)裝飾器設計 模式。
飾器就是一個可以接受調用也可以返回調用的函數(shù),該函數(shù)接受被裝飾的函數(shù)作為其位置參數(shù)。 裝飾器通過使用該參數(shù)來執(zhí)行某些操作,然后返回原始參數(shù)或一些其他的調用
函數(shù)也是對象,也可以當做參數(shù)傳遞
2. 裝飾器有什么用
可以考慮在裝飾器中置入通用功能的代碼來降低程序復雜度。例如,可以用裝飾器來:
引入日志
增加計時邏輯來檢測性能
給函數(shù)加入事務的能力
權限控制
3. 小 練 習
這里有個小練習,可以來試試哈 >-
用裝飾器實現(xiàn)權限控制
定義一個全局變量:username
定義add函數(shù),實現(xiàn)兩個數(shù)相加
實現(xiàn)login_required裝飾器,如果username值為root,提示"歡迎" 并計算結果,否則"沒有權限
代碼如下(示例):
三. 編寫和使用裝飾器
1. 小案例

2.應用注意事項
應用多個裝飾器
封裝時,至下而上
執(zhí)行時,至上而下
在實際應用的場景中,當我們采用上面的方式寫了兩個裝飾方法比如先驗證有沒有登錄 @login_required , 再驗證權限夠不夠時 @permision_allowed
3.保留元數(shù)據(jù)-什么是元數(shù)據(jù)
元數(shù)據(jù)(Metadata),又稱中介數(shù)據(jù)、中繼數(shù)據(jù),為描述數(shù)據(jù)的數(shù)據(jù)(data about data),主要是 描述數(shù)據(jù)屬性(property)的信息
函數(shù)的重要的元信息比如名字、文檔字符串、注解和參數(shù)簽名等
4.保留元數(shù)據(jù)-裝飾器后為什么元數(shù)據(jù)會丟失
因為return執(zhí)行的,是經(jīng)過調用封裝后的函數(shù)
5.保留元數(shù)據(jù)
利用**@functools.wraps(fun)**,將一個函數(shù)的重要內容復制到另一個函數(shù)
溫馨提醒:任何時候你定義裝飾器的時候,都應該使用 functools 庫中的 @wraps 裝飾器來注解底層 包裝函數(shù)。
6.小案例

7.內置的裝飾器
Python還提供了類裝飾器與**@staticmethod**,@classmethod,@property和這三個在面向對象編 程中常用的裝飾器
staticmethod:把類中定義的實例方法變成靜態(tài)方法
classmethod:把類中定義的實例方法變成類方法
property:把類中定義的實例方法變成類屬性。
四. 裝飾器的應用
1.為什么使用裝飾器
模塊化且清晰明確
代碼重用
裝飾器是顯式的,增強可讀性
2.在何處使用裝飾器
Python標準庫中包括很多包含裝飾器的模塊,并且很多常用工具和框架利用它們實現(xiàn)常功能,如,
要使用一個類上的方法不需要這個類的實例(@classmethod或@staticmethod)
mock模塊(單元測試python3.3后加入標準庫-@mock.patch或@mock.patch.object)
Django(@login_required, @permission_reqired)
Flask(@app.route) 充當url與函數(shù)之間的注冊表
Celery(@task) 返回Task類實例
插入日志、性能測試、事務處理、緩存、權限校驗等場景
記錄結果、增加計時邏輯來檢測性能等
五. 課后作業(yè)
1.實現(xiàn)函數(shù)注冊表

2.完善三創(chuàng)購物系統(tǒng)
所有用戶存放在Excel中(用戶名,密碼,余額)
定義裝飾器login_required,給需要的功能添加裝飾器
查看超市物品,不需要登錄 • 購物及查看余額,需要登錄
先驗證用戶是否已經(jīng)登錄(如果用戶未登錄提示“用戶未登錄,請登錄后重試”,并跳 轉到功能菜單)
總結
對于閉包的原理和好處十分重要,尤其是原理部分一定要好好消化一下,應用很廣泛。
對于裝飾器部分,要了解它是怎么應用的,在什么時候,什么地方應用,多寫幾個案例就明白了。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
您可能感興趣的文章:- Python 中閉包與裝飾器案例詳解
- Python必備基礎之閉包和裝飾器知識總結
- python高級語法之閉包和裝飾器詳解
- Python 中的函數(shù)裝飾器和閉包詳解
- python閉包的實例詳解