亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

Python 中的裝飾器

一, 引用

[書] 流暢的Python

[書] Effective Python

二, 基本概念

Python 中的裝飾器

問題1:裝飾器是什么?

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

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

解答: 裝飾器有2個(gè)特性,一是可以把被裝飾的函數(shù)替換成其他函數(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://www.vfuj.cn/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://www.vfuj.cn/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í)行順序是什么?

解答: 如果一個(gè)函數(shù)被多個(gè)裝飾器修飾,其實(shí)應(yīng)該是該函數(shù)先被最里面的裝飾器修飾后(下面例子中函數(shù)main()先被inner裝飾,變成新的函數(shù)),變成另一個(gè)函數(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

四, 標(biāo)準(zhǔn)庫中的裝飾器

Python 中的裝飾器

問題1: 標(biāo)準(zhǔn)庫中都有哪些裝飾器?

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

from?functools?import?lru_cache

from?functools?import?singledispatch

from?functools?import?wraps

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

解答: 使用裝飾器會(huì)產(chǎn)生我們可能不希望出現(xiàn)的副作用, 例如:改變被修飾函數(shù)名稱,對(duì)于調(diào)試器或者對(duì)象序列化器等需要使用內(nèi)省機(jī)制的那些工具,可能會(huì)無法正常運(yùn)行;其實(shí)調(diào)用裝飾器后,會(huì)將同一個(gè)作用域中原來函數(shù)同名的那個(gè)變量(例如下面的func_1),重新賦值為裝飾器返回的對(duì)象;使用@wraps后,會(huì)把與內(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://www.vfuj.cn/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è)計(jì)模式

Python 中的裝飾器

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

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

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

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

相關(guān)新聞

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