網站首頁 編程語言 正文
1 裝飾器背景知識
1.1 基本概念
裝飾器(Decorator)是 Python 中一種函數或類,用來修飾其他函數或類。裝飾器可以改變被裝飾函數的行為,或者在調用被裝飾函數之前和之后增加額外的操作。裝飾器的語法是使用 @ 語法符,在函數定義之前增加裝飾器函數的名稱。
@decorator_func def my_func(): pass
1.2 應用場景
- 代碼重用:裝飾器可以讓我們在不更改原函數代碼的情況下,為其添加額外的功能。
- 日志記錄:裝飾器可以記錄函數的調用日志,幫助我們追蹤程序的運行情況。
- 權限控制:裝飾器可以用來實現函數級別的權限控制,只允許特定的用戶訪問特定的函數。
- 緩存:裝飾器可以用來緩存函數的返回值,避免重復計算。
- 類型檢查:裝飾器可以用來在函數調用前檢查參數的類型是否符合要求。
- 裝飾器可以讓你在函數或類的定義中添加額外的邏輯,而不更改它們的實現。
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
函數。
- 裝飾器外部的return必須為裝飾器的內部函數,不含括號。通過代碼結構可以看出,裝飾器本身也是一個閉包。
- 在定義裝飾器
decorator_func
時,括號中的’func’指代被裝飾器裝飾的函數,在這段代碼中指代的就是my_func
函數。 - 在被裝飾器裝時候,函數的實際執行執行順序變成了內部函數
wrapper
所指定的順序。即先執行print(“Before calling the function”);再執行func()指代的my_func函數;最后執行print(“After calling the function”)。 - 本段代碼的最終輸出為:Before calling the function;Inside the function;After calling the function
3 使用裝飾器記錄函數執行次數
def cal_times(func): l=[] def wrapper(*var): l.append('1') func(*var) print("函數執行了%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)
函數中,我們增加了形參的輸入,因此,在裝飾器中,也要為之做出更改。此處裝飾器中的wrapper函數我們使用*var
傳參,這種設計方式的優點是可以讓這個裝飾器適用于任何函數。
再加入了cal_times
裝飾器后,函數每運行一次,都會使列表l
添加一個1,這樣可以計算函數的運行次數。這段代碼的運行結果如下:
4 帶參數的裝飾器
裝飾器與函數一樣,也可以帶入參數,我們在第二節的基礎上,對代碼做出如下修改:
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
函數調用前后打印額外的信息,并且裝飾器函數decorator_func
接受兩個參數,在調用wrapper
函數時使用這兩個參數。
最終,代碼將輸出:
Before calling the function with params: hello world; Inside the function;After calling the function。
如果同時還有字典類型的參數傳入,可以使用(*var,**_var)進行解決
5 裝飾器處理有返回值的函數
前面我們定義的函數都是執行某種功能,不涉及到return的相關操作。當涉及到處理有返回值的函數時,對于內部函數我們應該使用一個變量將函數的運行結果保存起來,并放在內層函數的return中。為了實現這一功能,我們將第三部分的代碼做出如下修改:
def cal_times(func): l=[] def wrapper(*var): l.append('1') result = func(*var) print("函數執行了%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)
對于這個裝飾器,我們在內部函數wrapper
使用result保存運行結果,并將result return,這樣a與b就可以被正常的賦值,運行結果如下圖。
而如果不執行保存result并return,a和b將不會得到任何值:
原文鏈接:https://blog.csdn.net/nkufang/article/details/128761627
相關推薦
- 2022-10-01 終于搞懂了Python中super(XXXX,?self).__init__()的作用了_pytho
- 2024-03-28 SpringBoot項目中的500錯誤
- 2022-06-06 Python實現為PDF去除水印的示例代碼_python
- 2022-05-11 使用git命令上傳代碼_其它綜合
- 2022-04-02 Docker中Dockerfile制作鏡像的方法步驟_docker
- 2023-01-15 C#實現虛擬鍵盤的實例詳解_C#教程
- 2022-07-29 pytest解讀fixture有效性及跨文件共享fixtures_python
- 2024-04-07 springmvc接受對象參數和MultipartFile參數的問題
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支