Python裝飾器的理解與使用教程

2022-09-23 11:45:12 字數 3307 閱讀 9152

python裝飾器(英文decorator)

本質是函式 為其他函式新增附加功能。裝飾器本身也是python的乙個重點,所以無論如何你必須弄懂它。裝飾器的存在其實就是為了在需要新增新功能時不影響之前版本的使用的同時來增加新功能,其實也是一種「偷懶」的辦法。它的使用場景較多,比如:插入日誌、效能測試、事務處理、快取、許可權校驗等場景。有了裝飾器,我們就可以抽離出大量與函式功能本身無關的雷同**並繼續重用。

python裝飾器的兩大原則:

(1)在不修改被修飾函式源**的同時為其增加功能

(2)不能修改被裝飾的函式的呼叫方式

python裝飾器使用詳解

裝飾器的使用其實也並非很複雜,只要你理解了它的基本原理以後,你便會愛上這個方法。在這裡做乙個簡單講解,所有的函式本身就是乙個「變數」,我們其實是可以直接把函式當作引數來進行傳遞的(但是在傳遞函式時不需要加括號,只需要函式名),其實傳遞函式的本質就是傳遞了函式的位址,拿到這個位址後加上括號就可以執行了。

(1)無引數的裝飾器

import time

# 裝飾器

def decorator(func): # func為裝飾器繫結的方法(繫結裝飾器後自動傳入)

def deco():

start_time = time.time()

func() # 呼叫test方法

end_time = time.time()

print("time:", end_time - start_time, "秒")

return deco # 返回deco方法

@decorator # 新增裝飾器

def test():

time.sleep(2)

print("run test")

test() # 呼叫函式(2)有引數的裝飾器

import time

# 裝飾器

def decorator(func): # func為裝飾器繫結的方法(繫結裝飾器後自動傳入)

def deco(arg1): # 傳入test方法的引數

start_time = time.time()

func(arg1) # 呼叫test方法

end_time = time.time()

print("time:", end_time - start_time, "秒")

return deco # 返回deco方法

@decorator # 新增裝飾器

def test(mstr):

time.sleep(2)

print("run test:"+mstr)

test("傳入引數") # 呼叫函式(3)裝飾器即可裝飾帶參函式也可以裝飾不帶參函式

import time

# 裝飾器

def decorator(func): # func為裝飾器繫結的方法(繫結裝飾器後自動傳入)

def deco(*arg1, **kwargs): # (傳入非固定引數)這樣即使裝飾函式不帶引數也可被裝飾

start_time = time.time()

func(*arg1, **kwargs)

end_time = time.time()

print("time:", end_time - start_time, "秒")

return deco # 返回deco方法

@decorator # 新增裝飾器

def test():

time.sleep(2)

print("run test:")

test() # 呼叫函式(4)裝飾器的高階使用

以上的裝飾器已經可以滿足基本需求了,但是他們第一存在乙個問題,被裝飾的函式的返回結果會被修改。

這裡我們模擬乙個登陸裝飾器,裝飾器需要對不同的被裝飾函式使用不同的登陸方法,並且是返回值不被修改。

user, password = 'db', '12345'

# 當裝飾器也需要參入引數時我們需要給裝飾器再加一層函式,

# 此時裝飾器接受到的方法需要進入第二層函式進行接受,

# 第一層需要接受裝飾器自己的引數

def login(login_type):

def outer_wrapper(func):

def wrapper(*agr1, **kwargs):

usernameinput = input("username:").strip()

passwordinput = input("password:").strip()

if login_type == "local":

if user == usernameinput and password == passwordinput:

print("login successful")

res = func(*agr1, **kwargs) # 接受返回結果

return res

else:

print("login fail")

elif login_type == "ldap":

print("遠端登入")

return wrapper

return outer_wrapper

def index():

print("welcome to index page")

@login(login_type="local") # 對裝飾分類

def home():

print("welcome to home page")

return "from home"

@login(login_type="ldap") # 對裝飾分類

def blog():

print("welcome to blog page")

index()

print(home())

blog()總結

(1) 要想裝飾器不修改被裝飾函式的返回值,我們需要在裝飾器中接受被裝飾函式的返回值並return即可。

(2) 如果希望對被裝飾函式進行分類處理,我們可以在繫結裝飾器時傳入乙個引數用於對被裝飾函式進行分類,但是這樣我們需要在裝飾器中在套一層函式,在第一層接收裝飾器傳遞的引數,在第二層函式中接收被裝飾函式。

(3) 如果希望裝飾器既能裝飾帶參的函式也可以修飾不帶參的函式,我們只需要在裝飾器中接收引數時,把引數定義為非固定引數即可。

python 裝飾器理解與使用

函式裝飾器在python中屬於比較高階但是卻實用並且常用的技術。常見的使用場景比如 要在類裡面實現乙個靜態方法 則需要使用 staticmethod裝飾器,類方法 classmethod則需要這個裝飾器。函式裝飾器有兩種使用方式,一種是帶引數的,一種是不帶引數的 先說第一種不帶引數的裝飾器使用方式 ...

python裝飾器理解 python裝飾器理解

裝飾器 在不改變原函式的 和呼叫方法的基礎上,給原函式增加額外的功能 理解宣告 為了方便理解,以下例子採用最簡潔的函式和新增的功能 給原函式新增乙個執行時間 import time def timer func def inner func return inner timer func timer...

python裝飾器 理解Python裝飾器

在python中,對於乙個函式,若想在其執行前後做點什麼,那麼裝飾器是再好不過的選擇,話不多說,上 usr bin env coding utf 8 script 01.py author howie from functools import wraps def decorator func wr...