久久国产乱子伦精品免费M,亚洲一区二区三区91,欧美国产在线视频,国产精品视频久久

Python 中的裝飾器

一, 引用

[書] 流暢的Python

[書] Effective Python

二, 基本概念

Python 中的裝飾器

問題1:裝飾器是什么?

解答: 嚴格來說,裝飾器只是語法糖, 裝飾器是可調(diào)用的對象,可以像常規(guī)的可調(diào)用對象那樣調(diào)用,特殊的地方是裝飾器的參數(shù)是一個函數(shù)

問題2:裝飾器有什么特性?

解答: 裝飾器有2個特性,一是可以把被裝飾的函數(shù)替換成其他函數(shù), 二是可以在加載模塊時候立即執(zhí)行

def?decorate(func):

????print('running decorate',?func)

????def?decorate_inner():

????????print('running decorate_inner function')

????????return?func()

????return?decorate_inner

 

<a?href="http://haohuigou.com/members/decorate">@decorate</a>

def?func_1():

????print('running func_1')

 

if?__name__?==?'__main__':

 

????print(func_1)

 

#返回值

running?decorate?<function func_1?at?0x7f29f644d268>

<function?decorate.<locals>.decorate_inner?at?0x7f29f641cb70>

問題3:如何使用被裝飾函數(shù)中的參數(shù)?

解答: 通過args 和 *kwargs 傳遞被修飾函數(shù)中的參數(shù)

def?decorate(func):

????def?decorate_inner(*args,?**kwargs):

????????print(type(args),?type(kwargs))

????????print('args',?args,?'kwargs',?kwargs)

????????return?func(*args,?**kwargs)

????return?decorate_inner

 

<a?href="http://haohuigou.com/members/decorate">@decorate</a>

def?func_1(*args,?**kwargs):

????print(args,?kwargs)

 

if?__name__?==?'__main__':

 

????func_1('1',?'2',?'3',?para_1='1',?para_2='2',?para_3='3')

 

#返回值

<class?'tuple'> <class?'dict'>

args?('1',?'2',?'3')?kwargs?{'para_2':?'2',?'para_1':?'1',?'para_3':?'3'}

('1',?'2',?'3')?{'para_2':?'2',?'para_1':?'1',?'para_3':?'3'}

三, 疊放裝飾器

Python 中的裝飾器

問題1:疊放裝飾器執(zhí)行順序是什么?

解答: 如果一個函數(shù)被多個裝飾器修飾,其實應(yīng)該是該函數(shù)先被最里面的裝飾器修飾后(下面例子中函數(shù)main()先被inner裝飾,變成新的函數(shù)),變成另一個函數(shù)后,再次被裝飾器修飾

def?outer(func):

????print('enter outer',?func)

????def?wrapper():

????????print('running outer')

????????func()

????return?wrapper

 

def?inner(func):

????print('enter inner',?func)

????def?wrapper():

????????print('running inner')

????????func()

????return?wrapper

 

@outer

@inner

def?main():

????print('running main')

 

if?__name__?==?'__main__':

 

????main()

 

#返回值

 

enter?inner?<function main?at?0x7fa1c96e8b70>

enter?outer?<function?inner.<locals>.wrapper?at?0x7fa1c96e8bf8>

running outer

running inner

running?main

四, 標準庫中的裝飾器

Python 中的裝飾器

問題1: 標準庫中都有哪些裝飾器?

解答: 標準庫中有多種裝飾器, 例如:裝飾方法的函數(shù)有property, classmethod, staticmethod; functools模塊中的lru_cache, singledispatch, ?wraps 等等

from?functools?import?lru_cache

from?functools?import?singledispatch

from?functools?import?wraps

問題2:為什么要使用@wraps裝飾器?它的作用是什么?

解答: 使用裝飾器會產(chǎn)生我們可能不希望出現(xiàn)的副作用, 例如:改變被修飾函數(shù)名稱,對于調(diào)試器或者對象序列化器等需要使用內(nèi)省機制的那些工具,可能會無法正常運行;其實調(diào)用裝飾器后,會將同一個作用域中原來函數(shù)同名的那個變量(例如下面的func_1),重新賦值為裝飾器返回的對象;使用@wraps后,會把與內(nèi)部函數(shù)(被修飾函數(shù),例如下面的func_1)相關(guān)的重要元數(shù)據(jù)全部復(fù)制到外圍函數(shù)(例如下面的decorate_inner)

from?functools?import?wraps

 

def?decorate(func):

????print('running decorate',?func)

????@wraps(func)

????def?decorate_inner():

????????print('running decorate_inner function',?decorate_inner)

????????return?func()

????return?decorate_inner

 

<a?href="http://haohuigou.com/members/decorate">@decorate</a>

def?func_1():

????print('running func_1',?func_1)

 

if?__name__?==?'__main__':

 

????func_1()

 

#返回值

running?decorate?<function func_1?at?0x7f145d2c2268>

running decorate_inner?function?<function func_1?at?0x7f145b9731e0>

running?func_1?<function func_1?at?0x7f145b9731e0>

五, 裝飾器設(shè)計模式

Python 中的裝飾器

問題1: 什么是裝飾器設(shè)計模式?

解答: 動態(tài)的給一個對象添加一些額外的職責,就擴展功能而言,裝飾器模式比子類化更加靈活,在設(shè)計模式中,裝飾器和組件都是抽象類,為了給具體的組件添加行為,具體的裝飾器實例要包裝具體組件的實例,即,裝飾器和所裝飾的組件接口一致,對使用該組建的客戶透明,將客戶的請求轉(zhuǎn)發(fā)給該組件,并且可能在轉(zhuǎn)發(fā)前后執(zhí)行一些額外的操作,透明性使得可以遞歸嵌套多個裝飾器,從而可以添加任意多個功能

問題2: Python中的裝飾器函數(shù)和設(shè)計模式中的裝飾器模式有什么關(guān)系?

解答: ?修飾器模式和Python修飾器之間并不是一對一的等價關(guān)系, Python裝飾器函數(shù)更為強大,不僅僅可以實現(xiàn)裝飾器模式。

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國內(nèi)好評如潮的Linux云計算運維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機構(gòu)!

    1. 主站蜘蛛池模板: 东城区| 贵溪市| 吉林市| 分宜县| 读书| 响水县| 阳江市| 黄梅县| 绩溪县| 海口市| 贞丰县| 清苑县| 巴塘县| 武山县| 临汾市| 柳州市| 沂水县| 游戏| 临湘市| 芜湖县| 赣榆县| 班戈县| 阳泉市| 山东省| 那坡县| 康定县| 兴宁市| 石景山区| 来宾市| 中超| 寿阳县| 新竹市| 永仁县| 涟水县| 安图县| 南江县| 平谷区| 青冈县| 汶上县| 临清市| 潢川县|