裝飾器詳解對小白友好

2021-10-03 06:21:06 字數 2725 閱讀 1459

裝飾器實質是函式,只是應用較廣,所以就直接叫做裝飾器,又叫做語法糖

def

func()

: var =

'hello,world'

print

(var)

definner()

: var =

'github'

print

(var)

# 執行

這個裡面包含兩個知識點,一是函式名其實也是一種變數,func這個函式名指向其所對應的函式封裝內容,而在func函式中,又在內定義了乙個inner函式。

函式定義後通過 函式名 + () 有的需要傳入引數)呼叫,而此處呼叫的是func()函式,先賦值變數var,輸出,再定義函式inner(),但inner函式並沒有被呼叫,所以列印的結果是hello,world

如下圖:

那怎麼樣才能呼叫inner呢?

先試試直接呼叫

這會出錯,說變數 inner 未被定義,這很好理解,因為 inner 這個函式名本身就是乙個變數,那麼就可以知道它是區域性變數,只在 func() 內起作用。所以這個 inner() 函式就是乙個閉包,它在func() 外不能被直接訪問。

那到底該怎麼做呢?

我們可以通過返回值來呼叫inner(),具體如下:

可以看到此次輸出了 github,這是因為func,inner都是變數,指向其所代表的函式。那麼將返回值 inner 其所指向的位址賦值給另乙個變數i,再通過 i() 就能訪問到閉包 inner() 。

裝飾器本質上就是乙個閉包。

顧名思義,裝飾器就是用來修飾某個函式,在不改變原來方法**和呼叫方式的前提下,額外的附加其他的功能和屬性。

先來看個例子

def

timer

(func)

:def

inner()

:# 閉包函式

具體過程是先以 fun1 為引數 呼叫 timer() 返回 inner ,並賦值給名為 fun2 的變數,再用fun2 + () 去呼叫 inner 所指向的閉包,若把 fun2 換成 fun1,則我們實現了不改變乙個函式的**,給乙個函式增加功能但不改變其呼叫方式。

現在來修改一下

可以看到這裡,呼叫fun1() 在結果中也列印出了 hello,world ,所以 @timer 的作用等效於 fun1 = timer(fun1) ,即把 fun1作為引數傳遞給裝飾器 timer() ,返回閉包函式名所指向的位址給 fun1,最後再通過fun1 呼叫。

更進一步,還可以新建乙個新檔案,匯入剛才的模組,如下

from sfd import fun1 # sfd 是我剛才寫入**的檔名

結果不變

除此之外,多個裝飾器也可以裝飾同乙個函式。

裝飾器詳解

1.不能修改被裝飾物件 函式 的源 封閉 2.不能更改被修飾物件 函式 的呼叫方式,且能達到增加功能的效果 開放 把要被裝飾的函式作為外層函式的引數通過閉包操作後返回乙個替代版函式 被裝飾的函式 fn 外層函式 outer func outer fn func fn 替代版函式 return inn...

python裝飾器 python 裝飾器詳解

def outer x def inner y return x y return inner print outer 6 5 11 如 所示,在outer函式內,又定義了乙個inner函式,並且inner函式又引用了外部函式outer的變數x,這就是乙個閉包了。在輸出時,outer 6 5 第乙個...

python裝飾器詳解 python裝飾器詳解

按照 python 的程式設計原則,當乙個函式被定義後,如要修改或擴充套件其功能應盡量避免直接修改函式定義的 段,否則該函式在其他地方被呼叫時將無法正常執行。因此,當需要修改或擴充套件已被定義的函式的功能而不希望直接修改其 時,可以使用裝飾器。先來看乙個簡單的例子 def func1 functio...