Python的裝飾器

2021-10-13 04:42:46 字數 4713 閱讀 5410

在軟體開發過程中,不同的階段設計開發時會定義一些函式,而後期的開發過程中,希望擴充套件一些裝飾這個函式的內容,即裝飾器;舉例如下

存在乙個計算兩個數相加的函式

def

add(a , b)

:'''

求任意兩個數的和

'''r = a + b

return r

res = add(

123,

456)

print

(res)

執行結果:

579

希望在執行這個計算前程式輸出"計算開始…";計算時輸出"計算結束…" 前提是不能改變原函式;如下所示

#定義乙個函式,達到需求的設計

defnew_add

(a,b)

:print

('計算開始~~~'

) r = add(a,b)

print

('計算結束~~~'

)return r

r = new_add(

111,

456)

print

(r)執行結果

計算開始~~~

計算結束~~~

567

以上的設計雖然完成了需求,但是相對應的也帶來了一些問題

為了解決這個問題,建立乙個可以自動的生產函式

# 用於計算兩個數相加

defadd

(a,b)

: r = a+b

return r

# 用於計算兩個數相乘

defmul

(a,b)

: r = a*b

return r

defdecorators

(fun)

:'''

這是乙個裝飾器函式

用來對其他函式進行擴充套件,使其他函式可以在執行前列印開始執行,執行後列印執行結束

引數:fun 要擴充套件的函式物件

'''# 建立乙個新函式

''' *args 用於接收所有的位置引數

**kwargs 用於接受所有的關鍵字引數

'''defnew_fun

(*args,

**kwargs)

:#將引數裝包成元組或字典

print

('計算開始...'

)# 呼叫被擴充套件的函式

num = fun(

*args,

**kwargs)

#將元組拆包成位置引數,將字典拆包成關鍵字引數

print

('計算結束...'

)# 返回函式的執行結果

return num

# 返回新函式

return new_fun

# 呼叫

r = decorators(add)

# 將裝飾器函式的返回值函式,即內部的函式給到r

print

(r)# r就是裝飾器函式的內部函式的記憶體位址

res = r(

123,

456)

# 向內部函式傳參,相當於add(123,456)

print

(res)

執行結果

<

locals

>

.new_fun at 0x0000016afffb6950

>

計算開始...

計算結束...

579

計算兩個數相乘的情況,如下呼叫

r = decorators(add)

print

(r)res = r(

123,

456)

print

(res)

print

('-'*30

)r = decorators(mul)

print

(r)res = r(2,

3)print

(res)

執行結果

<

locals

>

.new_fun at 0x000001d00b7168c8

>

計算開始...

計算結束...

579---

----

----

----

----

----

----

---<

locals

>

.new_fun at 0x000001d00b716950

>

計算開始...

計算結束...

6

可見,每次呼叫裝飾器函式的內部函式時,分配的記憶體肯定是不一樣的,傳入的add、mul實參就是真實計算的函式內容

如下所示:函式裝飾器的內容不變,只是在定義函式的時候加上@裝飾器函式的名稱即可

但是這樣一來,裝飾器就與函式實體進行了繫結,以後呼叫函式時都會攜帶裝飾器

def

decorators

(fun)

:'''

這是乙個裝飾器

用來對其他函式進行擴充套件,使其他函式可以在執行前列印開始執行,執行後列印執行結束

引數:fun 要擴充套件的函式物件

'''# 建立乙個新函式

''' *args 用於接收所有的位置引數

**kwargs 用於接受所有的關鍵字引數

'''defnew_fun

(*args,

**kwargs)

:#將引數裝包成元組或字典

print

('計算開始...'

)# 呼叫被擴充套件的函式

num = fun(

*args,

**kwargs)

#將元組拆包成位置引數,將字典拆包成關鍵字引數

print

('計算結束...'

)# 返回函式的執行結果

return num

# 返回新函式

return new_fun

# 對函式實體進行裝飾

@decorators

defadd

(a,b)

: r = a+b

return r

@decorators

defmul

(a,b)

: r = a*b

return r

# 呼叫

res = add(

123,

456)

print

(res)

print

('-'*30

)res = r(2,

3)print

(res)

計算開始...

計算結束...

579---

----

----

----

----

----

----

---計算開始...

計算結束...

6

def

fn1(fun)

:def

new_function

(*args ,

**kwargs)

:print

('fn1裝飾~開始執行~~~~'

) result = fun(

*args ,

**kwargs)

print

('fn1裝飾~執行結束~~~~'

)return result

return new_function

deffn2

(fun)

:def

new_function

(*args ,

**kwargs)

:print

('fn2裝飾~開始執行~~~~'

) result = fun(

*args ,

**kwargs)

print

('fn2裝飾~執行結束~~~~'

)return result

return new_function

@fn1

@fn2

defsay_hello()

:print()

say_hello(

)

由內到外的執行就是,以say_hello()函式的輸出結果為中心,先使用fn2裝飾器,然後使用fn1裝飾器

執行結果

fn1裝飾~開始執行~~~

~fn2裝飾~開始執行~~~

~~~fn2裝飾~執行結束~~~

~fn1裝飾~執行結束~~~

~

改變順序

@fn2

@fn2

defsay_hello()

:print()

say_hello(

)執行結果

fn2裝飾~開始執行~~~

~fn1裝飾~開始執行~~~

~~~fn1裝飾~執行結束~~~

~fn2裝飾~執行結束~~~

~

python裝飾器 Python 裝飾器

簡言之,python裝飾器就是用於拓展原來函式功能的一種函式,這個函式的特殊之處在於它的返回值也是乙個函式,使用python裝飾器的好處就是在不用更改原函式的 前提下給函式增加新的功能。一般而言,我們要想拓展原來函式 最直接的辦法就是侵入 裡面修改,例如 這是我們最原始的的乙個函式,然後我們試圖記錄...

python裝飾器 裝飾器

由於函式也是乙個物件,而且函式物件可以被賦值給變數,所以,通過變數也能呼叫該函式。def now print 2015 3 25 f now f 2015 3 25 函式物件有乙個 name 屬性,可以拿到函式的名字 now.name now f.name now 現在,假設我們要增強now 函式的...

python裝飾器原理 Python裝飾器原理

裝飾器 decorator 是物件導向設計模式的一種,這種模式的核心思想是在不改變原來核心業務邏輯 的情況下,對函式或類物件進行額外的修飾。python中的裝飾器由python直譯器直接支援,其定義形式如下 decorator def core service 要理解上述 的含義,我們從自定義函式裝...