Python裝飾器使用方法全面梳理
1 裝飾器背景知識
1.1 基本概念
裝飾器(Decorator)是 Python 中一種函數(shù)或類,用來修飾其他函數(shù)或類。裝飾器可以改變被裝飾函數(shù)的行為,或者在調(diào)用被裝飾函數(shù)之前和之后增加額外的操作。裝飾器的語法是使用 @ 語法符,在函數(shù)定義之前增加裝飾器函數(shù)的名稱。
@decorator_func def my_func(): pass
1.2 應用場景
- 代碼重用:裝飾器可以讓我們在不更改原函數(shù)代碼的情況下,為其添加額外的功能。
- 日志記錄:裝飾器可以記錄函數(shù)的調(diào)用日志,幫助我們追蹤程序的運行情況。
- 權(quán)限控制:裝飾器可以用來實現(xiàn)函數(shù)級別的權(quán)限控制,只允許特定的用戶訪問特定的函數(shù)。
- 緩存:裝飾器可以用來緩存函數(shù)的返回值,避免重復計算。
- 類型檢查:裝飾器可以用來在函數(shù)調(diào)用前檢查參數(shù)的類型是否符合要求。
- 裝飾器可以讓你在函數(shù)或類的定義中添加額外的邏輯,而不更改它們的實現(xiàn)。
2 簡單的裝飾器代碼
def decorator_func(func): def wrapper(): print("Before calling the function") func() print("After calling the function") return wrapper @decorator_func def my_func(): print("Inside the function") my_func() # Output: Before calling the function # Inside the function # After calling the function
上面展示了最簡單的裝飾器示例代碼。在代碼中,我們建立了一個名為decorator_func
的裝飾器和一個名為my_func
函數(shù)。
- 裝飾器外部的return必須為裝飾器的內(nèi)部函數(shù),不含括號。通過代碼結(jié)構(gòu)可以看出,裝飾器本身也是一個閉包。
- 在定義裝飾器
decorator_func
時,括號中的’func’指代被裝飾器裝飾的函數(shù),在這段代碼中指代的就是my_func
函數(shù)。 - 在被裝飾器裝時候,函數(shù)的實際執(zhí)行執(zhí)行順序變成了內(nèi)部函數(shù)
wrapper
所指定的順序。即先執(zhí)行print(“Before calling the function”);再執(zhí)行func()指代的my_func函數(shù);最后執(zhí)行print(“After calling the function”)。 - 本段代碼的最終輸出為:Before calling the function;Inside the function;After calling the function
3 使用裝飾器記錄函數(shù)執(zhí)行次數(shù)
def cal_times(func): l=[] def wrapper(*var): l.append('1') func(*var) print("函數(shù)執(zhí)行了%s次"%(len(l))) return wrapper @cal_times def my_func(i): print('%s的平方是%s'%(i,i**2)) my_func(5) my_func(6)
在my_func(i)
函數(shù)中,我們增加了形參的輸入,因此,在裝飾器中,也要為之做出更改。此處裝飾器中的wrapper函數(shù)我們使用*var
傳參,這種設(shè)計方式的優(yōu)點是可以讓這個裝飾器適用于任何函數(shù)。
再加入了cal_times
裝飾器后,函數(shù)每運行一次,都會使列表l
添加一個1,這樣可以計算函數(shù)的運行次數(shù)。這段代碼的運行結(jié)果如下:
4 帶參數(shù)的裝飾器
裝飾器與函數(shù)一樣,也可以帶入?yún)?shù),我們在第二節(jié)的基礎(chǔ)上,對代碼做出如下修改:
def decorator_func(param1, param2): def decorator(func): def wrapper(): print("Before calling the function with params:", param1,param2) func() print("After calling the function") return wrapper return decorator @decorator_func("hello", "world") def my_func(): print("Inside the function") my_func()
這段代碼使用了裝飾器來在my_func
函數(shù)調(diào)用前后打印額外的信息,并且裝飾器函數(shù)decorator_func
接受兩個參數(shù),在調(diào)用wrapper
函數(shù)時使用這兩個參數(shù)。
最終,代碼將輸出:
Before calling the function with params: hello world; Inside the function;After calling the function。
如果同時還有字典類型的參數(shù)傳入,可以使用(*var,**_var)進行解決
5 裝飾器處理有返回值的函數(shù)
前面我們定義的函數(shù)都是執(zhí)行某種功能,不涉及到return的相關(guān)操作。當涉及到處理有返回值的函數(shù)時,對于內(nèi)部函數(shù)我們應該使用一個變量將函數(shù)的運行結(jié)果保存起來,并放在內(nèi)層函數(shù)的return中。為了實現(xiàn)這一功能,我們將第三部分的代碼做出如下修改:
def cal_times(func): l=[] def wrapper(*var): l.append('1') result = func(*var) print("函數(shù)執(zhí)行了%s次"%(len(l))) return result return wrapper @cal_times def my_func(i): print('%s的平方是%s'%(i,i**2)) return i**2 a = my_func(5) b = my_func(6) print(a,b)
對于這個裝飾器,我們在內(nèi)部函數(shù)wrapper
使用result保存運行結(jié)果,并將result return,這樣a與b就可以被正常的賦值,運行結(jié)果如下圖。
而如果不執(zhí)行保存result并return,a和b將不會得到任何值:
到此這篇關(guān)于Python裝飾器使用方法全面梳理的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 地圖經(jīng)緯度轉(zhuǎn)換、糾偏的實例代碼
這篇文章主要介紹了python 地圖經(jīng)緯度轉(zhuǎn)換、糾偏的實例代碼,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08PyQt5中QPushButton的用法詳細解析與應用實戰(zhàn)
PyQt5 是一個用于創(chuàng)建圖形用戶界面的 Python 綁定庫,它基于 Qt5 應用程序框架,在 PyQt5 中,QPushButton 是一個常用的控件,用于創(chuàng)建按鈕,允許用戶通過點擊來觸發(fā)某些操作,本文將詳細介紹 QPushButton 的用法,并通過實際案例來展示其強大的功能2024-07-07Pycharm搭建Django項目詳細教程(看完這一篇就夠了)
這篇文章主要給大家介紹了關(guān)于Pycharm搭建Django項目的詳細教程,想要學習的小伙伴看完這一篇就夠了,pycharm是一種Python?IDE,帶有一整套可以幫助用戶在使用Python語言開發(fā)時提高其效率的工具,需要的朋友可以參考下2023-11-11