【后端】【python】利用反射器----動態設置裝飾器

📘 Python 裝飾器進階指南


一、裝飾器本質

? 本質概念

Python 裝飾器的本質是 函數嵌套 + 返回函數,它是對已有函數的增強,不修改原函數代碼,使用語法糖 @decorator 實現包裹效果。

def my_decorator(func):def wrapper(*args, **kwargs):print("Before")result = func(*args, **kwargs)print("After")return resultreturn wrapper@my_decorator
def say_hello():print("Hello!")

? 裝飾器其實是這樣的調用:

say_hello = my_decorator(say_hello)

二、元數據保持:functools.wraps

? 問題

普通裝飾器會丟失原函數的元數據,如 __name__, __doc__ 等。

? 解決方案:使用 functools.wraps

from functools import wrapsdef my_decorator(func):@wraps(func)def wrapper(*args, **kwargs):print("Running:", func.__name__)return func(*args, **kwargs)return wrapper

🌟 好處

  • 文檔自動生成工具能識別原始函數
  • 保持調試友好、函數簽名保留

三、反射 + 動態設置裝飾器

? 場景:你不想在函數上一個個手動寫 @裝飾器,而是運行時自動批量裝飾。

示例:動態為某類中所有特定方法添加裝飾器

def my_log_decorator(func):@wraps(func)def wrapper(*args, **kwargs):print(f"[LOG] {func.__name__} 被調用")return func(*args, **kwargs)return wrapperclass MyClass:def method_a(self): print("A")def method_b(self): print("B")# 動態裝飾
for name in ['method_a', 'method_b']:method = getattr(MyClass, name)setattr(MyClass, name, my_log_decorator(method))obj = MyClass()
obj.method_a()

四、進階實踐:Django DRF + 動態文檔裝飾器

? 背景

使用 drf-spectacular 時,需要為 ViewSet 方法添加 @extend_schema,但方法多、內容重復,適合動態處理。

💡 做法:定義映射 + 動態應用裝飾器

from drf_spectacular.utils import extend_schema
from functools import wraps
from rest_framework import viewsetsclass SchemaModelViewSet(viewsets.ModelViewSet):schema_summary_mapping = {'list': "獲取{name}列表",'retrieve': "獲取單個{name}",'create': "創建{name}",'update': "更新{name}",'partial_update': "局部更新{name}",'destroy': "刪除{name}"}# 動態應用裝飾器
def _apply_schema_decorators():for method_name, summary_tpl in SchemaModelViewSet.schema_summary_mapping.items():if hasattr(SchemaModelViewSet, method_name):base_method = getattr(viewsets.ModelViewSet, method_name)@wraps(base_method)def dynamic_wrapper(*args, **kwargs):return base_method(*args, **kwargs)decorated = extend_schema(summary=summary_tpl.format(name="對象"))(dynamic_wrapper)setattr(SchemaModelViewSet, method_name, decorated)_apply_schema_decorators()

? 優點

  • 方法不需要手動一個個寫裝飾器
  • 支持格式化 summary,按模型/資源名稱自動生成
  • 保持方法原始簽名與元數據,文檔準確生成

五、進階技巧匯總

技巧說明
@wraps(func)保持元數據,推薦用于所有自定義裝飾器
動態裝飾使用 getattr + setattr 為方法動態添加裝飾器
裝飾器工廠裝飾器接收參數時需要多層函數嵌套
多重裝飾多個裝飾器可層層嵌套處理邏輯
類裝飾器__call__ 方法定義類裝飾器

六、結語

裝飾器是 Python 函數式編程的核心工具,掌握以下幾點,就可以自由應對開發中的各種裝飾器需求:

  • 理解函數對象 & 嵌套函數原理
  • 使用 wraps 保持元信息
  • 動態反射結合裝飾器進行自動化增強
  • 在大型框架(如 Django DRF)中實現文檔或權限的自動化控制

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

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

相關文章

Nodejs Express框架

參考:Node.js Express 框架 | 菜鳥教程 第一個 Express 框架實例 接下來我們使用 Express 框架來輸出 "Hello World"。 以下實例中我們引入了 express 模塊,并在客戶端發起請求后,響應 "Hello World" 字符串。 創建 e…

Docker Swarm 集群

Docker Swarm 集群 本文檔介紹了 Docker Swarm 集群的基本概念、工作原理以及相關命令使用示例,包括如何在服務調度中使用自定義標簽。本文檔適用于需要管理和擴展 Docker 容器化應用程序的生產環境場景。 1. 什么是 Docker Swarm Docker Swarm 是用于管理 Docker…

充電寶項目中的MQTT(輕量高效的物聯網通信協議)

文章目錄 補充:HTTP協議MQTT協議MQTT的核心特性MQTT vs HTTP:關鍵對比 EMQX項目集成EMQX集成配置客戶端和回調方法具體接口和方法處理處理類 補充:HTTP協議 HTTP是一種應用層協議,使用TCP作為傳輸層協議,默認端口是80…

【iOS】UIPageViewController學習

UIPageViewController學習 前言創建一個UIPageViewController最簡單的使用 UIPageViewController的方法說明:效果展示 UIPageViewController的協議方法 前言 筆者最近在寫項目時想實現一個翻書效果,上網學習到了UIPageViewController今天寫本篇博客總結…

Linux搭建環境:從零開始掌握基礎操作(四)

? ? 您好,我是程序員小羊! 前言 軟件測試第一步就是搭建測試環境,如何搭建好測試環境,需要具備兩項的基礎知識: 1、Linux 命令: 軟件測試第一個任務, 一般都需要進行環境搭建, 一部分,環境搭建內容是在服…

一天一個java知識點----Tomcat與Servlet

認識BS架構 靜態資源:服務器上存儲的不會改變的數據,通常不會根據用戶的請求而變化。比如:HTML、CSS、JS、圖片、視頻等(負責頁面展示) 動態資源:服務器端根據用戶請求和其他數據動態生成的,內容可能會在每次請求時都…

YOLOV8 OBB 海思3516訓練流程

YOLOV8 OBB 海思3516訓練流程 目錄 1、 下載帶GPU版本的torch(可選) 1 2、 安裝 ultralytics 2 3、 下載pycharm 社區版 2 4、安裝pycharm 3 5、新建pycharm 工程 3 6、 添加conda 環境 4 7、 訓練代碼 5 9、配置Ymal 文件 6 10、修改網絡結構 9 11、運行train.py 開始訓練模…

【深度學習】花書第18章——配分函數

直面配分函數 許多概率模型(通常是無向圖模型)由一個未歸一化的概率分布 p ~ ( x , θ ) \tilde p(\mathbf x,\theta) p~?(x,θ)定義。我們必須通過除以配分函數 Z ( θ ) Z(\pmb{ \theta}) Z(θ)來歸一化 p ~ \tilde p p~?。以獲得一個有效的概率分…

工作記錄1

日常總結、靈感記錄、學習要點。持續記錄 學海無涯,再好的記性也比不過爛筆頭,記錄一下學習日常、靈感、要點。 前言:最近看見一個博文,很有感觸,是某個大佬自己運營的網站,分享了他的各種經驗文章和自身的一些筆記。本人還沒有他這么屌,所以還是先在CSDN上小試牛刀吧…

Spring Boot(二十一):RedisTemplate的String和Hash類型操作

RedisTemplate和StringRedisTemplate的系列文章詳見: Spring Boot(十七):集成和使用Redis Spring Boot(十八):RedisTemplate和StringRedisTemplate Spring Boot(十九)…

智能指針之設計模式1

本文探討一下智能指針和GOF設計模式的關系,如果按照設計模式的背后思想來分析,可以發現圍繞智能指針的設計和實現有設計模式的一些思想體現。當然,它們也不是嚴格意義上面向對象的設計模式,畢竟它們沒有那么分明的類層次體系&…

中間件--ClickHouse-1--基礎介紹(列式存儲,MPP架構,分布式計算,SQL支持,向量化執行,億萬級數據秒級查詢)

1、概述 ClickHouse是一個用于聯機分析(OLAP)的列式數據庫管理系統(DBMS)。它由俄羅斯的互聯網巨頭Yandex為解決其內部數據分析需求而開發,并于2016年開源。專為大規模數據分析,實時數據分析和復雜查詢設計,具有高性能、實時數據和可擴展性等…

Go之Slice和數組:深入理解底層設計與最佳實踐

在Go語言中,數組(Array)和切片(Slice)是兩種看似相似卻本質不同的數據結構。本文將深入剖析它們的底層實現機制,并結合實際代碼示例,幫助開發者掌握核心差異和使用場景。 一、基礎概念&#xff…

力扣熱題100——普通數組(不普通)

普通數組但一點不普通! 最大子數組和合并區間輪轉數組除自身以外數組的乘積缺失的第一個正數 最大子數組和 這道題是非常經典的適用動態規劃解決題目,但同時這里給出兩種解法 動態規劃、分治法 那么動態規劃方法大家可以在我的另外一篇博客總結中看到&am…

矩陣基礎+矩陣轉置+矩陣乘法+行列式與逆矩陣

GPU渲染過程 矩陣 什么是矩陣(Matrix) 向量 (3,9,88) 點乘:計算向量夾角 叉乘:計算兩個向量構成平面的法向量。 矩陣 矩陣有3行,2列,所以表示為M32 獲取固…

MySQL之text字段詳細分類說明

在 MySQL 中,TEXT 是用來存儲大量文本數據的數據類型。TEXT 類型可以存儲非常長的字符串,比 VARCHAR 類型更適合存儲大塊的文本數據。TEXT 數據類型分為以下幾個子類型,每個子類型用于存儲不同大小范圍的文本數據: TINYTEXT: 可以…

超詳細!Android 面試題大匯總與深度解析

一、Java 與 Kotlin 基礎 1. Java 的多態是如何實現的? 多態是指在 Java 中,同一個行為具有多個不同表現形式或形態的能力。它主要通過方法重載(Overloading)和方法重寫(Overriding)來實現。 方法重載&a…

如何提高webrtc操作跟手時間,降低延遲

第一次做webrtc項目,操作延遲,一直是個問題,多次調試都不能達到理想效果。偶爾發現提高jitterBuffer時間可以解決此問題。關鍵代碼 const _setJitter (values: number) > { const receives peerConnection.getReceivers();receives.f…

語音合成(TTS)從零搭建一個完整的TTS系統-第一節-效果演示

一、概述 語音合成又叫文字轉語音(TTS-text to speech ),本專題我們記錄從零搭建一個完整的語音合成系統,包括文本前端、聲學模型和聲碼器,從模型訓練到系統的工程化實現,模型可以部署在手機等嵌入式設備上…

實驗三 I/O地址譯碼

一、實驗目的 掌握I/O地址譯碼電路的工作原理。 二、實驗電路 實驗電路如圖1所示,其中74LS74為D觸發器,可直接使用實驗臺上數字電路實驗區的D觸發器,74LS138為地址譯碼器, Y0:280H~287H&…