【Python学习教程】:装饰器的详细教程,通俗易懂
裝飾器是Python中的一個(gè)重要概念,多用于在不修改原函數(shù)的基礎(chǔ)上,為函數(shù)增加額外的功能。
基礎(chǔ)裝飾器
例如小李給女朋友買了一款iPhone12作為生日禮物,手機(jī)原封未拆封。
def gift():print('iPhone12')gift() # 運(yùn)行顯示禮物信息但還是覺得禮物太單薄,于是又買了一盒德芙巧克力,一支dior的口紅,并找了個(gè)精美的禮品盒包裝了一下,盒子里放滿了泡沫球。
''' 學(xué)習(xí)中遇到問題沒人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' def gift():print('iPhone12')def box(gift):print('='*5 + '禮物盒' + '='*5)print('一盒泡沫球')print('好多巧克力')print('一支dior口紅')return giftgift = box(gift) # 將禮物包裝后作為禮物 gift() # 顯示禮物信息運(yùn)行后顯示如下:
=====禮物盒===== 一盒泡沫球 好多巧克力 一支dior口紅 iPhone12這個(gè)box便是一個(gè)裝飾器,它的參數(shù)是一個(gè)函數(shù)對(duì)象,同數(shù)字、字符串、列表、字典等數(shù)據(jù)類型一樣,函數(shù)和類也可以作為函數(shù)的參數(shù)使用,畢竟在Python里人人平等,一切皆對(duì)象。
box在使用時(shí)依然返回了原來的gift,只是在拿到這個(gè)gift之前增加了兩個(gè)額外的驚喜,然后我們把box作為gift使用即可。
裝飾器本質(zhì)上就是以函數(shù)作為參數(shù),對(duì)函數(shù)做一些處理,并替換原函數(shù)的一種高階函數(shù)。
上例中,使用裝飾器表示為如下。
運(yùn)行后顯示和上例相同。
處理函數(shù)參數(shù)
小李突然想到,買哪個(gè)顏色應(yīng)該征詢下女友的意見,也就是原來的gift應(yīng)支持一個(gè)可供選擇的顏色參數(shù)。
def gift(color):print(f'iPhone12{color}版')作為一個(gè)細(xì)心的boyfriend,小李需要根據(jù)對(duì)應(yīng)的手機(jī)顏色選擇同樣顏色的泡沫球,也就是需要能獲取到,被裝飾的gift函數(shù)的參數(shù)。
這時(shí)候我們需要在盒子內(nèi)部(box裝飾器),重新準(zhǔn)備一個(gè)新的禮物,根據(jù)顏色參數(shù)做不同的處理,然后根據(jù)顏色拿到指定的iPhone12禮物。
在box內(nèi)部為了根據(jù)參數(shù)做對(duì)應(yīng)處理,我們新建了一個(gè)函數(shù),函數(shù)內(nèi)部也可以定義內(nèi)部函數(shù),內(nèi)部函數(shù)new_gift可以獲取并使用外部box函數(shù)的參數(shù),如gift。
為了能獲取到原有函數(shù)gift的參數(shù),我們需要建立一個(gè)傀儡函數(shù)new_gift,這個(gè)函數(shù)和原函數(shù)gift的參數(shù)一致、返回結(jié)果一致,即new_gift('紅色')返回的就是gift(‘紅色’)。
然后貍貓換太子,不再返回原來的gift函數(shù)對(duì)象,而是返回替換的new_gift函數(shù)對(duì)象。
運(yùn)行后顯示
=====禮物盒===== 一盒紅色泡沫球 好多巧克力 一支dior口紅 iPhone12紅色版注意:在裝飾器box里,要返回一個(gè)函數(shù)對(duì)象,如上例中的return gift或本例中的return new_gift。而在傀儡函數(shù)new_gift中,為了和原函數(shù)gift結(jié)果一致,要返回原函數(shù)的調(diào)用結(jié)果即gift(color)。
從普遍意義上講,作為商家,為了裝飾器box可以包裝任何形式的禮物,無論禮物有什么參數(shù)都可以滿足,這就要求我們的傀儡函數(shù)new_gift支持任意類型的參數(shù)即def new_gift(*args, **kwargs)。
然后把無論什么參數(shù)*args,**kwargs交由原函數(shù)gift(*args, **kwargs)處理即可。
修改后,我們便得到一個(gè)通用的裝飾器,可以包裝任何禮物。
這樣,無論被裝飾的函數(shù)有幾個(gè)參數(shù),box裝飾器都可以正常處理。
運(yùn)行后顯示如下。
帶參裝飾器
信心滿滿的小李覺得,在盒子上還可以做些文章,要根據(jù)女友的喜好選擇不同形狀的箱子,因此我們需要根據(jù)參數(shù)來定制我們的裝飾器box,在盒子外面再加一層定制函數(shù)。
def custom_box(shape): # 根據(jù)參數(shù)定制裝飾器def box(gift): # 裝飾器函數(shù)print('='*5 + f'{shape}禮物盒' + '='*5) # 根據(jù)形狀定制# ...return box # 返回裝飾器函數(shù)此時(shí)我們得到一個(gè)可以根據(jù)參數(shù)進(jìn)行定制的裝飾器函數(shù)custom_box,這個(gè)裝飾器接收到參數(shù)后,傳遞給真實(shí)裝飾器box,并返回定制后box裝飾器函數(shù)。
完整代碼如下。
''' 學(xué)習(xí)中遇到問題沒人解答?小編創(chuàng)建了一個(gè)Python學(xué)習(xí)交流QQ群:531509025 尋找有志同道合的小伙伴,互幫互助,群里還有不錯(cuò)的視頻學(xué)習(xí)教程和PDF電子書! ''' def custom_box(shape): # 根據(jù)參數(shù)定制裝飾器 =====================def box(gift): # 實(shí)際的裝飾器函數(shù) ---------------------------print('='*5 + f'{shape}禮物盒' + '='*5)def new_gift(*args, **kwargs): # 傀儡函數(shù) ..............if args and len(args) > 0:color = args[0]print(f'一盒{color}泡沫球')else:print(f'一盒泡沫球')print('好多巧克力')print('一支dior口紅')result = gift(*args, **kwargs)return result # 返回原函數(shù)結(jié)果 ......................return new_gift # 返回傀儡函數(shù) ---------------------------return box # 返回定制的裝飾器 ===============================@custom_box('心形') # 使用可定制的裝飾器 def gift(color, pro=False): if pro is True:print(f'iPhone12 Pro{color}版')else:print(f'iPhone12{color}版')gift('海藍(lán)色', pro=True)注意:裝飾器在導(dǎo)入模塊時(shí)立即計(jì)算的,即沒調(diào)用gift(‘海藍(lán)色’, pro=True)之前就已經(jīng)執(zhí)行生成定制后的box。
運(yùn)行后,結(jié)果如下。
=====心形禮物盒===== 一盒海藍(lán)色泡沫球 好多巧克力 一支dior口紅 iPhone12 Pro海藍(lán)色版總結(jié)
以上是生活随笔為你收集整理的【Python学习教程】:装饰器的详细教程,通俗易懂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Python学习教程】推导式与生成器
- 下一篇: Python中必学知识点:类方法、实例方