成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

裝飾器是怎么實現的?你學會了嗎?

開發 前端
解釋器還是從上到下解釋,當執行到 @deco1 的時候,肯定要裝飾了,但它下面不是函數,也是一個裝飾器,于是表示:要不哥們,你先裝飾。然后執行 @deco2,但它下面還是一個裝飾器,于是重復了剛才的話,把皮球踢給 @deco3。

裝飾器是 Python 的一個亮點,但并不神秘,因為它本質上就是高階函數加上閉包,只不過給我們提供了一個優雅的語法糖。

至于為什么要有裝飾器,我覺得有句話說的非常好,裝飾器存在的最大意義就是可以在不改動原函數的代碼和調用方式的情況下,為函數增加一些新的功能。

def deco(func):
    print("都閃開,我要開始裝飾了")

    def inner(*args, **kwargs):
        print("開始了")
        ret = func(*args, **kwargs)
        print("結束")
        return ret

    return inner

# 這一步等價于 foo = deco(foo)
# 因此上來就會打印 deco 里面的 print
@deco
def foo(a, b):
    print(f"a = {a},b = ")
print("---------")
"""
都閃開,我要開始裝飾了
---------
"""

# 此時再調用 foo,已經不再是原來的 foo 了
# 而是 deco 里面的閉包 inner
foo(1, 2)
"""
開始了
a = 1,b = 2
結束
"""

如果不使用裝飾器的話:

def deco(func):
    print("都閃開,我要開始裝飾了")

    def inner(*args, **kwargs):
        print("開始了")
        ret = func(*args, **kwargs)
        print("結束")
        return ret

    return inner

def foo(a, b):
    print(f"a = {a},b = ")

foo = deco(foo)
"""
都閃開,我要開始裝飾了
"""
foo(1, 2)
"""
開始了
a = 1,b = 2
結束
"""

打印結果告訴我們,裝飾器只是類似于 foo=deco(foo) 的一個語法糖罷了。

至于字節碼這里就不看了,還是那句話,只是個語法糖,它和我們直接調用 foo=deco(foo) 是等價的,所以理解裝飾器(decorator)的關鍵就在于理解閉包(closure)。

另外函數在被裝飾器裝飾之后,整個函數其實就已經變了,而為了保留原始信息我們一般會從 functools 模塊中導入一個 wraps 函數。當然裝飾器還可以寫的更復雜,比如帶參數的裝飾器、類裝飾器等等,不過這些都屬于 Python 層級的東西了,我們就不說了。

另外裝飾器還可以不止一個,如果一個函數被多個裝飾器裝飾,會有什么表現呢?

def deco1(func):
    def inner():
        return f"<deco1>{func()}</deco1>"
    return inner

def deco2(func):
    def inner():
        return f"<deco2>{func()}</deco2>"
    return inner

def deco3(func):
    def inner():
        return f"<deco3>{func()}</deco3>"
    return inner

@deco1
@deco2
@deco3
def foo():
    return "古明地覺"

print(foo())

解釋器還是從上到下解釋,當執行到 @deco1 的時候,肯定要裝飾了,但它下面不是函數,也是一個裝飾器,于是表示:要不哥們,你先裝飾。然后執行 @deco2,但它下面還是一個裝飾器,于是重復了剛才的話,把皮球踢給 @deco3。

當執行 @deco3 的時候,發現下面終于是一個普通的函數了,于是裝飾了。

deco3 裝飾完畢之后,foo = deco3(foo)。然后 deco2 發現 deco3 已經裝飾完畢,那么會對 deco3 裝飾的結果再進行裝飾,此時 foo = deco2(deco3(foo));同理,再經過 deco1 的裝飾,最終得到了 foo  =  deco1(deco2(deco3(foo)))。

于是最終輸出:

<deco1><deco2><deco3>古明地覺</deco3></deco2></deco1>

所以當有多個裝飾器的時候,會從下往上裝飾;然后執行的時候,會從上往下執行。

以上就是裝飾器相關的內容,可以說非常簡單了,甚至有點水文章的嫌疑,因為核心都在上一篇介紹的閉包當中。還是那句話,理解裝飾器的關鍵就在于理解閉包。

責任編輯:武曉燕 來源: 古明地覺的編程教室
相關推薦

2023-12-27 09:32:47

SQL語句數據

2022-06-16 07:50:35

數據結構鏈表

2024-08-09 08:17:07

SSH服務器架構

2023-12-11 08:03:01

Java線程線程組

2023-03-17 16:44:44

Channel進程模型

2023-01-28 10:40:56

Java虛擬機代碼

2023-12-07 12:29:49

Nginx負載均衡策略

2024-03-12 08:37:32

asyncawaitJavaScript

2024-07-29 10:35:44

KubernetesCSI存儲

2022-11-09 07:20:43

調用日志502報錯nginx

2024-02-02 11:03:11

React數據Ref

2022-07-08 09:27:48

CSSIFC模型

2023-08-01 12:51:18

WebGPT機器學習模型

2024-01-02 12:05:26

Java并發編程

2024-01-19 08:25:38

死鎖Java通信

2024-02-04 00:00:00

Effect數據組件

2023-07-26 13:11:21

ChatGPT平臺工具

2023-01-10 08:43:15

定義DDD架構

2023-06-15 14:10:00

kubeletCNI插件

2022-03-05 23:29:18

LibuvwatchdogNode.js
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 羞羞视频在线观看 | www国产成人免费观看视频,深夜成人网 | 日韩视频一区二区三区 | 午夜网| 国产成人精品网站 | 国产96在线| 视频一区二区中文字幕日韩 | 精品在线一区 | 男人的天堂久久 | av在线三级 | 2021天天干夜夜爽 | 最新国产精品视频 | 亚洲精品无 | 国产一区二区视频免费在线观看 | 97精品超碰一区二区三区 | 国产线视频精品免费观看视频 | 国产成人av在线 | 中文字幕日韩欧美一区二区三区 | 日韩精品1区2区 | 亚洲不卡| 欧美视频三区 | 韩国毛片一区二区三区 | 在线一区二区三区 | 成人精品视频在线观看 | 一级大黄 | 亚洲精品第一 | 香蕉一区二区 | 一区二区三区影院 | 国产一区不卡在线观看 | 一级二级三级黄色 | 国产美女一区二区 | 亚州精品成人 | 黄色在线免费观看 | 99精品欧美一区二区三区 | 精品久久久久久久 | 精品三级在线观看 | 亚洲欧洲一区二区 | 久久久蜜桃 | 国产精品久久久久久久7777 | 瑞克和莫蒂第五季在线观看 | 欧美激情视频网站 |