Python中的裝飾器詳解

2021-09-17 18:40:09 字數 3693 閱讀 5057

1.裝飾器介紹

2.語法糖

3.裝飾器的應用

4.多個裝飾器的使用

1.裝飾器介紹:

裝飾器就是對被裝飾的物件(類,函式)進行重構的,可以在不改變原來物件的情況下呼叫物件時執行重構的行為,在不改變原函式的基礎上,給函式增加功能。

特點:把乙個函式當作引數,返回乙個替代版的函式,本質就是乙個返回函式的函式

def func1():

print('hello,world')

#如果我們想要實現的功能是在此基礎上在列印一句話怎麼辦,

#有人會說直接在函式內部在寫上對應的功能就好了,可是在生

#產環境中往往是不能修改已經寫好的**的,那麼怎麼辦呢

def outer():

func1() #呼叫前面的函式

print('login...')

outer()

#這種方法貌似可以實現,可是功能複雜後每次都要呼叫還是不合理的

使用裝飾器
def desc(fun):

def add_info():

print('國慶快樂~')

fun()

return add_info

@desc ##語法糖,用來連線裝飾器和函式

def login():

print('login...')

@desc

def logout():

print('logout...')

login()

logout()

函式執行順序:在執行login()的時候,由於有裝飾器,所以先執行裝飾器,執行print函式,fun()跳到login()函式,然後返回到裝飾器發現函式執行完畢,跳到login()

此函式執行完畢

執行結果

國慶快樂~

login...

國慶快樂~

logout...

2.裝飾器的應用
import time

def decorator(func):

print(time.time()) #列印系統時間

func()

@decorator

def f1():

print('this is a function...')

@decorator

def f2():

print('this is a function...')

f1()

f2()

執行結果

1554977829.1020477

this is a function...

1554977829.1020703

this is a function...

語法糖連承接之後,裝飾器從上到下執行

3.裝飾器中帶有引數

import time

def decorator(func):

def warpper(*args,**kwargs): #裝飾器中可以加引數,如可變引數,關鍵字引數

print(time.time())

func(*args,**kwargs)

return warpper

@decorator

def f1(func_name):

print('this is a function ' + func_name)

@decorator

def f2(func_name1,func_name2):

print('this is a function ' + func_name1)

print('this is a function ' + func_name2)

@decorator

def f3(func_name1,func_name2,**kwargs):

print('this is a function ' + func_name1)

print('this is a function ' + func_name2)

print(kwargs)

f1('test')

f2('test1','test2')

f3('test1','test2',a=1,b=2,c='westos')

執行結果:

1554978357.8987756

this is a function test

1554978357.8988152

this is a function test1

this is a function test2

1554978357.898822

this is a function test1

this is a function test2

4.有返回值的裝飾器
import time

import functools

def add_log(fun):

@functools.wraps(fun)

start_time = time.time()

res = fun(*args,**kwargs) #函式本身有返回值,要在函式最後將資料返回,不然在呼叫函式的時候

end_time = time.time() #無法得到結果,只是在函式內部執行

return res

@add_log

def add(x,y):

time.sleep(1)

return x + y

add(1,2)

執行結果

5.多個裝飾器

如果要新增複雜的功能的時候,乙個裝飾器遠遠不過,如何新增多個裝飾器呢

def decorator_a(fun):

print('get in decorator_a')

def inner_a(*args, **kwargs):

print('get in inner_a')

res = fun(*args, **kwargs)

return res

return inner_a

def decorator_b(fun):

print('get in decorator_b')

def inner_b(*args, **kwargs):

print('get in inner_b')

res = fun(*args, **kwargs)

return res

return inner_b

@decorator_a #當有多個裝飾器的是裝飾器由下到上執行,即先執行b在在執行a

@decorator_b

def f(x):

print('get in f')

return x * 2

f(2)

執行結果:

get in decorator_b

get in decorator_a

get in inner_a

get in inner_b

get in f

python中的裝飾器詳解

在了解裝飾器的之前一定要先了解函式作為引數傳遞,什麼是函式內嵌,請參考我之前寫的部落格函式簡介 因為在python裡面,函式也是物件,也可以作為引數進行傳遞.python裝飾器本質也是一種特殊函式,它接收的引數是函式物件,然後動態地函式引數新增額外的功能,而不用修改原有的函式物件.python裝飾器...

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...