国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - Python裝飾器基礎(chǔ)詳解

Python裝飾器基礎(chǔ)詳解

2020-08-15 15:31GEJUNQIANG Python

裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數(shù)、方法或者類進(jìn)行加工。接下來通過本文給大家介紹python裝飾器基礎(chǔ),對python裝飾器相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧

裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數(shù)、方法或者類進(jìn)行加工。在Python中,我們有多種方法對函數(shù)和類進(jìn)行加工,比如在Python閉包中,我們見到函數(shù)對象作為某一個函數(shù)的返回結(jié)果。相對于其它方式,裝飾器語法簡單,代碼可讀性高。因此,裝飾器在Python項(xiàng)目中有廣泛的應(yīng)用。

前面快速介紹了裝飾器的語法,在這里,我們將深入裝飾器內(nèi)部工作機(jī)制,更詳細(xì)更系統(tǒng)地介紹裝飾器的內(nèi)容,并學(xué)習(xí)自己編寫新的裝飾器的更多高級語法。

什么是裝飾器

裝飾是為函數(shù)和類指定管理代碼的一種方式。Python裝飾器以兩種形式呈現(xiàn):

【1】函數(shù)裝飾器在函數(shù)定義的時(shí)候進(jìn)行名稱重綁定,提供一個邏輯層來管理函數(shù)和方法或隨后對它們的調(diào)用。

【2】類裝飾器在類定義的時(shí)候進(jìn)行名稱重綁定,提供一個邏輯層來管理類,或管理隨后調(diào)用它們所創(chuàng)建的實(shí)例。

簡而言之,裝飾器提供了一種方法,在函數(shù)和類定義語句的末尾插入自動運(yùn)行的代碼——對于函數(shù)裝飾器,在def的末尾;對于類裝飾器,在class的末尾。這樣的代碼可以扮演不同的角色。
裝飾器提供了一些和代碼維護(hù)性和審美相關(guān)的有點(diǎn)。此外,作為結(jié)構(gòu)化工具,裝飾器自然地促進(jìn)了代碼封裝,這減少了冗余性并使得未來變得更容易。

函數(shù)裝飾器

通過在一個函數(shù)的def語句的末尾運(yùn)行另一個函數(shù),把最初的函數(shù)名重新綁定到結(jié)果。

用法

裝飾器在緊挨著定義一個函數(shù)或方法的def語句之前的一行編寫,并且它由@符號以及緊隨其后的對于元函數(shù)的一個引用組成——這是管理另一個函數(shù)的一個函數(shù)(或其他可調(diào)用對象)。
在編碼上,函數(shù)裝飾器自動將如下語法:

?
1
2
3
4
@decorator
def F(arg):
...
F(99)

映射為這個對等形式:

?
1
2
3
4
def F(arg):
...
F = decorator(F)
F(99)

這里的裝飾器是一個單參數(shù)的可調(diào)用對象,它返回與F具有相同數(shù)目的參數(shù)的一個可調(diào)用對象。
當(dāng)隨后調(diào)用F函數(shù)的時(shí)候,它自動調(diào)用裝飾器所返回的對象。

換句話說,裝飾實(shí)際把如下的第一行映射為第二行(盡管裝飾器只在裝飾的時(shí)候運(yùn)行一次)

?
1
2
fun(6,7)
decorator(func)(6,7)

這一自動名稱重綁定也解釋了之前介紹的靜態(tài)方法和property裝飾器語法的原因:

?
1
2
3
4
5
class C:
@staticmethod
def meth(...):...
@property
def name(self):...

實(shí)現(xiàn)

裝飾器自身是返回可調(diào)用對象的可調(diào)用對象。實(shí)際上,它可以是任意類型的可調(diào)用對象,并且返回任意類型的可調(diào)用對象:函數(shù)和類的任何組合都可以使用,盡管一些組合更適合于特定的背景。

有一種常用的編碼模式——裝飾器返回了一個包裝器,包裝器把最初的函數(shù)保持到一個封閉的作用域中:

?
1
2
3
4
5
6
7
8
9
def decorator(F):
def wrapper(*args):
# 使用 F 和 *args
# 調(diào)用原來的F(*args)
return wrapper
@decorator
def func(x,y):
...
func(6,7)

當(dāng)隨后調(diào)用名稱func的時(shí)候,它確實(shí)調(diào)用裝飾器所返回的包裝器函數(shù);隨后包裝器函數(shù)可能運(yùn)行最初的func,因?yàn)樗谝粋€封閉的作用域中仍然可以使用。

為了對類做同樣的事情,我們可以重載調(diào)用操作:

?
1
2
3
4
5
6
7
8
9
10
class decorator:
def __init__(self,func):
self.func = func
def __call__(self,*args):
# 使用self.func和args
# self.func(*args)調(diào)用最初的func
@decorator
def func(x,y):
...
func(6,7)

但是,要注意的是,基于類的代碼中,它對于攔截簡單函數(shù)有效,但當(dāng)它應(yīng)用于類方法函數(shù)時(shí),并不很有效:
如下反例:

?
1
2
3
4
5
6
7
8
9
class decorator:
def __init__(self,func):
self.func = func
def __call__(self,*args):
# 調(diào)用self.func(*args)失敗,因?yàn)镃實(shí)例參數(shù)無法傳遞
class C:
@decorator
def method(self,x,y):
...

這時(shí)候裝飾的方法重綁定到一個類的方法上,而不是一個簡單的函數(shù),這一點(diǎn)帶來的問題是,當(dāng)裝飾器的方法__call__隨后運(yùn)行的時(shí)候,其中的self接受裝飾器類實(shí)例,并且類C的實(shí)例不會包含到一個*args中。

這時(shí)候,嵌套函數(shù)的替代方法工作得更好:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def decorator:
def warpper(*args):
# ...
return wrapper
@decorator
def func(x,y):
...
func(6,7)
class C:
@decorator
def method(self,x,y):
...
x = C()
x.method(6,7)

類裝飾器

類裝飾器與函數(shù)裝飾器使用相同的語法和非常相似的編碼方式。類裝飾器是管理類的一種方式,或者用管理或擴(kuò)展類所創(chuàng)建的實(shí)例的額外邏輯,來包裝實(shí)例構(gòu)建調(diào)用。

用法

假設(shè)類裝飾器返回一個可調(diào)用對象的一個單參數(shù)的函數(shù),類裝飾器的語法為:

?
1
2
3
4
@decorator
class C:
...
x = C(99)

等同于下面的語法:

?
1
2
3
4
class C:
...
C = decorator(C)
x = C(99)

直接效果是隨后調(diào)用類名會創(chuàng)建一個實(shí)例,該實(shí)例會觸發(fā)裝飾器所返回的可調(diào)用對象,而不是調(diào)用最初的類自身。

實(shí)現(xiàn)

類裝飾器返回的可調(diào)用對象,通常創(chuàng)建并返回最初的類的一個新的實(shí)例,以某種方式來擴(kuò)展對其接口的管理。例如,下面的實(shí)例插入一個對象來攔截一個類實(shí)例的未定義的屬性:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
def decorator(cls):
class Wrapper:
def __init__(self,*args):
self.wrapped = cls(*args)
def __getattr__(self,name):
return getattr(self.wrapped,name)
return Wrapper
@decorator
class C: # C = decorator(C)
def __init__(self,x,y): # Run by Wrapper.__init__
self.attr = 'spam'
x = C(6,7) # 等價(jià)于Wrapper(6,7)
print(x.attr)

在這個例子中,裝飾器把類的名稱重新綁定到另一個類,這個類在一個封閉的作用域中保持了最初的類。

就像函數(shù)裝飾器一樣,類裝飾器通常可以編寫為一個創(chuàng)建并返回可調(diào)用對象的“工廠”函數(shù)。

裝飾器嵌套

有時(shí)候,一個裝飾器不夠,裝飾器語法允許我們向一個裝飾器的函數(shù)或方法添加包裝器邏輯的多個層。這種形式的裝飾器的語法為:

?
1
2
3
4
5
@A
@B
@C
def f(...):
...

如下這樣轉(zhuǎn)換:

?
1
2
3
def f(...):
...
f = A(B(C(f)))

這里,最初的函數(shù)通過3個不同的裝飾器傳遞,每個裝飾器處理前一個結(jié)果。

裝飾器參數(shù)

函數(shù)裝飾器和類裝飾器都能接受參數(shù),如下:

?
1
2
3
4
@decorator(A,B)
def F(arg):
...
F(99)

自動映射到其對等形式:

?
1
2
3
4
def F(arg):
...
F = decorator(A,B)(F)
F(99)

裝飾器參數(shù)在裝飾之前就解析了,并且它們通常用來保持狀態(tài)信息供隨后的調(diào)用使用。例如,這個例子中的裝飾器函數(shù),可能采用如下形式:

?
1
2
3
4
5
6
7
def decorator(A,B):
# 保存或使用A和B
def actualDecorator(F):
# 保存或使用函數(shù) F
# 返回一個可調(diào)用對象
return callable
return actualDecorator

以上,這是裝飾器的基礎(chǔ)知識,接下來將學(xué)習(xí)編寫自己的裝飾器。

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 国产精品久久久久久久久久久久冷 | 久久a视频 | 在线色网| 91免费在线视频 | 黄色毛片在线看 | 日本不卡免费新一二三区 | 日韩精品一二三区 | 中文字幕av在线播放 | 国产福利91精品一区二区三区 | 国产精品无码久久久久 | 日韩欧美不卡 | 欧美精品一区二区在线观看 | www.色小妹.com| 久久久婷婷 | 青青久视频 | 欧美成人二区 | a级黄色在线观看 | 91麻豆精品国产91久久久更新时间 | caoporn最新地址 | 久色成人 | www.av在线 | 亚洲综合中文字幕在线观看 | 国产成人精品免高潮在线观看 | 国产高潮呻吟av | 久久久国产视频 | 色a综合| 国产一区二区精品在线观看 | 一级黄色大片免费观看 | 一区二区国产精品 | 黄色免费在线观看 | 欧美午夜精品久久久久久人妖 | 欧美日韩综合视频 | 99re视频在线观看 | 欧美国产激情二区三区 | 国产精品久久久久久久久久久免费看 | 91免费视频观看 | 欧美亚洲一区二区三区 | 中文字幕日韩视频 | 久久午夜精品 | 精品久久精品 | 国产精品美女 |