【Python】Python 裝飾器的用法總結

在 Python 中,裝飾器(Decorator) 是一種設計模式,用于在不修改函數或類代碼的情況下動態地擴展其功能。裝飾器廣泛應用于日志記錄、性能監控、權限驗證等場景,提供了一種簡潔優雅的方式來“包裹”現有的代碼。本文將介紹裝飾器的基本概念、使用方式及常見場景。


1. 什么是裝飾器?

裝飾器是一個 高階函數,它接受一個函數或類作為輸入,并返回一個新的函數或類,通常用于增加額外的功能。通過裝飾器,我們可以在不修改原始代碼的情況下擴展函數或類的行為。裝飾器的核心思想是 “包裝”,它用來增強或修改目標函數或類的功能。

2. 裝飾器的基本語法

裝飾器的基本語法形式是:

@decorator_function
def target_function():pass

等價于:

def target_function():passtarget_function = decorator_function(target_function)

3. 創建一個簡單的函數裝飾器

函數裝飾器的實現通常包含兩個函數:一個是裝飾器本身,另一個是“包裝函數”。包裝函數會在原始函數執行前后執行自定義邏輯。

示例:簡單的日志裝飾器
def log_decorator(func):def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")result = func(*args, **kwargs)print(f"Function {func.__name__} finished")return resultreturn wrapper@log_decorator
def say_hello(name):print(f"Hello, {name}!")say_hello("Alice")

輸出:

Calling function: say_hello
Hello, Alice!
Function say_hello finished

解釋:

  • log_decorator 是裝飾器,它接收 say_hello 函數作為參數,返回一個新的函數 wrapperwrapper 在執行 say_hello 之前和之后打印日志。

4. 帶參數的裝飾器

裝飾器本身可以帶參數,這時需要增加額外的嵌套層級。這樣可以讓裝飾器在使用時更加靈活。

示例:帶參數的裝飾器
def repeat_decorator(repeat_count):def decorator(func):def wrapper(*args, **kwargs):for _ in range(repeat_count):result = func(*args, **kwargs)return resultreturn wrapperreturn decorator@repeat_decorator(repeat_count=3)
def say_hello(name):print(f"Hello, {name}!")say_hello("Alice")

輸出:

Hello, Alice!
Hello, Alice!
Hello, Alice!

解釋:

  • repeat_decorator 裝飾器可以接受一個 repeat_count 參數,表示函數執行的次數。在 wrapper 函數中,調用目標函數多次。

5. 類裝飾器

除了函數裝飾器,Python 也支持類裝飾器,用于修改或增強類的行為。

示例:類裝飾器
def add_method(cls):def new_method(self):print("This is a new method")cls.new_method = new_methodreturn cls@add_method
class MyClass:def greet(self):print("Hello!")obj = MyClass()
obj.greet()      # 調用原方法
obj.new_method() # 調用新添加的方法

輸出:

Hello!
This is a new method

解釋:

  • add_method 裝飾器給 MyClass 類添加了一個新的方法 new_method。通過 @add_method 裝飾器,類 MyClass 被修改,新增了一個方法。

6. 使用 functools.wraps 保持原函數屬性

當我們使用裝飾器時,目標函數的元數據(如函數名、文檔字符串等)會被包裝函數覆蓋。為了保留原函數的屬性,我們可以使用 functools.wraps 裝飾器。

示例:使用 wraps 保持元數據
from functools import wrapsdef log_decorator(func):@wraps(func)def wrapper(*args, **kwargs):print(f"Calling function: {func.__name__}")return func(*args, **kwargs)return wrapper@log_decorator
def say_hello(name):"""Say hello to someone."""print(f"Hello, {name}!")print(say_hello.__name__)  # 輸出函數的名字
print(say_hello.__doc__)   # 輸出函數的文檔字符串

輸出:

say_hello
Say hello to someone.

解釋:

  • 使用 @wraps(func) 保證了裝飾器函數 wrapper 保留了原始函數 say_hello 的名字和文檔字符串。

7. 常見應用場景

7.1 緩存結果(Memoization)

裝飾器可以用于緩存函數的返回結果,避免重復計算,提升性能。

示例:緩存裝飾器
def memoize(func):cache = {}def wrapper(*args):if args not in cache:cache[args] = func(*args)return cache[args]return wrapper@memoize
def slow_function(x):print(f"Computing {x}...")return x * xprint(slow_function(5))
print(slow_function(5))  # 緩存值,不會重復計算

輸出:

Computing 5...
25
25
7.2 權限驗證

裝飾器常用于在執行函數前進行權限驗證或用戶身份檢查。

示例:權限驗證裝飾器
def requires_permission(func):def wrapper(user, *args, **kwargs):if not user.get("is_admin", False):raise PermissionError("User does not have permission")return func(user, *args, **kwargs)return wrapper@requires_permission
def delete_user(user, username):print(f"Deleting user {username}")user = {"name": "Alice", "is_admin": False}
delete_user(user, "Bob")  # 拋出權限錯誤

8. 總結

裝飾器是 Python 中的一項強大功能,能夠讓我們以非常簡潔的方式在不改變原始代碼的情況下增加功能。它們不僅適用于函數,也可以用于類、方法等。裝飾器常常用于日志記錄、緩存、權限驗證等場景,在 Python 開發中十分常見。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/84134.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/84134.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/84134.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【C++】控制臺小游戲

移動&#xff1a;W向上&#xff0c;S上下&#xff0c;A向左&#xff0c;D向右 程序代碼&#xff1a; #include <iostream> #include <conio.h> #include <windows.h> using namespace std;bool gameOver; const int width 20; const int height 17; int …

「MATLAB」計算校驗和 Checksum

什么是校驗和 是一個算法&#xff0c;將一串數據累加&#xff0c;得到一個和。 MATLAB程序 function c_use Checksum(packet) %Checksum 求校驗和 % 此處checksum提供詳細說明checksum 0;for i 1:length(packet)value hex2dec(packet(i));checksum checksum value; …

JavaScript面試題之消息隊列

JavaScript消息隊列詳解&#xff1a;單線程的異步魔法核心 在JavaScript的單線程世界中&#xff0c;消息隊列&#xff08;Message Queue&#xff09;是實現異步編程的核心機制&#xff0c;它像一位高效的調度員&#xff0c;讓代碼既能“一心多用”又避免卡頓。本文將深入剖析消…

京東外賣分潤系統部署實操!0門檻入駐+全平臺接入+自定義比例...這些人,賺翻了!

隨著京東外賣的發展勢頭日漸迅猛&#xff0c;許多創業者們的態度也逐漸從原本的觀望轉變為了切實的行動&#xff0c;并開始通過各個渠道詢問起了京東外賣自動分潤系統部署相關的各項事宜&#xff0c;連帶著以京東外賣自動分潤系統質量哪家強為代表的多個問題&#xff0c;也成為…

【辦公類-18-06】20250523(Python)“口腔檢查涂氟信息”批量生成打印(學號、姓名、學校、班級、身份證、戶籍、性別、民族)

背景需求: 6月是常規體檢,前幾天發了體檢表(驗血單),用Python做了姓名等信息的批量打印 【辦公類-18-04】20250520(Python)“驗血單信息”批量生成打印(學校、班級、姓名、性別)-CSDN博客文章瀏覽閱讀969次,點贊19次,收藏11次。【辦公類-18-04】20250520(Python)…

Python郵件處理:POP與SMTP

poplib簡介 poplib 是Python 3中的官方郵件庫&#xff0c;實現了POP的標準&#xff1a;RFC1939&#xff0c;用于郵件的收取。與之類似的還有imaplib 。 &#xff08;注&#xff1a;本文僅拿pop舉例&#xff09; poplib的使用方法&#xff0c;就是幾步&#xff1a; 先創建一…

IP風險度自檢,多維度守護網絡安全

如今IP地址不再只是網絡連接的標識符&#xff0c;更成為評估安全風險的核心維度。IP風險度通過多維度數據建模&#xff0c;量化IP地址在網絡環境中的安全威脅等級&#xff0c;已成為企業反欺詐、內容合規、入侵檢測的關鍵工具。據Gartner報告顯示&#xff0c;2025年全球78%的企…

Flink集成資源管理器

Flink集成資源管理器 Apache Flink 支持多種資源管理器&#xff0c;主要包括以下幾種?&#xff1a; YARN ResourceManager ?&#xff1a;適用于使用 Hadoop YARN 作為資源管理器的環境。YARN ResourceManager 負責管理集群中的資源&#xff0c;包括 CPU、內存等&#xff0c;并…

upload 文件上傳審計

目錄 LOW Medium HIgh Impossible 概述 很多Web站點都有文件上傳的接口&#xff08;比如注冊時上傳頭像等&#xff09;&#xff0c;由于沒有對上傳的文件類型進行嚴格限制&#xff0c;導致可以上傳一些文件&#xff08;比如Webshell&#xff09;。 上傳和SQL、XSS等都是主流…

【freertos-kernel】list

freertos list 基本類型結構體ListItem_t &#xff08;list.h&#xff09;List_t &#xff08;list.h&#xff09; 宏函數函數vListInitialisevListInitialiseItemvListInsertEndvListInsertuxListRemove 基本類型 freertos為了兼容性&#xff0c;重新定義了基本類型&#xff…

游戲盾的功有哪些?

游戲盾的功能主要包括以下幾方面&#xff1a; 一、網絡攻擊防護 DDoS攻擊防護&#xff1a; T級防御能力&#xff1a;游戲盾提供分布式云節點防御集群&#xff0c;可跨地區、跨機房動態擴展防御能力和負載容量&#xff0c;輕松達到T級別防御&#xff0c;有效抵御SYN Flood、UD…

PycharmFlask 學習心得:路由(3-4)

對路由的理解&#xff1a; 用戶輸入網址 例如&#xff1a;http://localhost:5000/hello 瀏覽器會向這個地址發起一個 HTTP 請求&#xff08;比如 GET 請求&#xff09; 請求到達 Flask 的服務器 Flask 監聽著某個端口&#xff08;如 5000&#xff09;&#xff0c;收到請求后…

課程與考核

6.1 課程講解與實戰考核 6.1.1 SQL注入篇考核 考核目標&#xff1a;通過手動注入與工具結合&#xff0c;獲取目標數據庫敏感信息。 題目示例&#xff1a; 目標URL&#xff1a;http://vuln-site.com/product?id1 要求&#xff1a; 判斷注入類型&#xff08;聯合查詢/報錯注…

線程池介紹,分類,實現(工作原理,核心組成,拒絕策略),固態線程池的實現+詳細解釋(支持超時取消機制和不同的拒絕策略)

目錄 線程池 介紹 分類 實現 工作原理 核心組成 拒絕策略 固態線程池 功能 std::future 實現 拒絕策略支持 提交任務 超時取消 用戶檢測取消 安全銷毀 代碼 測試 線程池 介紹 線程池(圖解,本質,模擬實現代碼),添加單例模式(懶漢思路代碼)_線程池單例-CSDN博…

紡線機與PLC通訊故障?ETHERCAT/CANopen網關秒解協議難題

在紡織行業智能化轉型浪潮中&#xff0c;設備間高效通信是實現自動化生產的關鍵。JH-ECT009疆鴻智能EtherCAT轉CANopen協議轉換網關&#xff0c;憑借出色的協議適配能力&#xff0c;成功架起倍福PLC與自動紡線機間的通信橋梁&#xff0c;為紡織廠自動化生產注入強勁動力。 紡織…

深度剖析并發I/O模型select、poll、epoll與IOCP核心機制

核心概要&#xff1a;select、poll、epoll 和 IOCP 是四種用于提升服務器并發處理能力的I/O模型或機制。前三者主要屬于I/O多路復用范疇&#xff0c;允許單個進程或線程監視多個I/O流的狀態&#xff1b;而 IOCP 則是一種更為徹底的異步I/O模型。 一、引言&#xff1a;為何需要這…

microsoft中word如何添加個人簽名

https://support.microsoft.com/zh-cn/office/%E6%8F%92%E5%85%A5%E7%AD%BE%E5%90%8D-f3b3f74c-2355-4d53-be89-ae9c50022730 插入簽名圖片 圖片格式選擇裁剪合適的大小 使用的簽名如果不是白色紙張的話可以重新著色 依次點擊圖片格式——顏色——重新著色——黑白50% 設置透…

linux初識--基礎指令

Linux下基礎指令 ls 指令 語法&#xff1a; ls [ 選項 ] [ ?錄或?件 ] 功能&#xff1a;對于?錄&#xff0c;該命令列出該?錄下的所有??錄與?件。對于?件&#xff0c;將列出?件名以及其他信 息。 常?選項&#xff1a; -a 列出?錄下的所有?件&#xff0c;包括以…

實戰:Dify智能體+Java=自動化運營工具!

我們在運營某個圈子的時候&#xff0c;可能每天都要將這個圈子的“熱門新聞”發送到朋友圈或聊天群里&#xff0c;但依靠傳統的實現手段非常耗時耗力&#xff0c;我們通常要先收集熱門新聞&#xff0c;再組裝要新聞內容&#xff0c;再根據內容設計海報等。 那怎么才能簡化并高…

RabbitMQ可靠傳輸——持久性、發送方確認

一、持久性 前面學習消息確認機制時&#xff0c;是為了保證Broker到消費者直接的可靠傳輸的&#xff0c;但是如果是Broker出現問題&#xff08;如停止服務&#xff09;&#xff0c;如何保證消息可靠性&#xff1f;對此&#xff0c;RabbitMQ提供了持久化功能&#xff1a; 持久…