day27/60重寫(補充)

DAY 27 函數專題2:裝飾器

ps:第一期day27對應5月16日

知識點回顧:

  1. 裝飾器的思想:進一步復用
  2. 函數的裝飾器寫法
  3. 注意內部函數的返回值

作業:

編寫一個裝飾器 logger,在函數執行前后打印日志信息(如函數名、參數、返回值)

@logger
def multiply(a, b):return a * bmultiply(2, 3)  
# 輸出:
# 開始執行函數 multiply,參數: (2, 3), {}
# 函數 multiply 執行完畢,返回值: 6

本期內容如果無法理解,可以參考如下視頻教學

B站-裝飾器的使用


豆包:

以下是用生活場景比喻解釋裝飾器相關知識點,幫你秒懂這個「代碼魔術」:

1. 裝飾器的思想:給函數「穿外套」的復用藝術

本質:在不修改原函數代碼的前提下,給函數「添加額外功能」,就像給衣服縫上口袋、給蛋糕加奶油。
核心目的:避免重復寫相似代碼(比如多個函數都需要「日志記錄」功能),實現代碼復用。

?

比喻

?
  • 裝飾器 =?禮物包裝紙
    • 原函數 = 「禮物本身」(比如一本書)。
    • 裝飾器 = 「包裝紙 + 蝴蝶結」(給禮物增加「美觀」功能)。
    • 關鍵規則:不能拆開禮物修改內容(不修改原函數代碼),但可以在外面套包裝。
?

生活場景舉例

?
  • 原函數?read_book()?是「看書」,裝飾器可以是「記錄看書時間」的功能:

    python

    運行

    def 記錄時間(原函數):  # 裝飾器函數,參數是原函數def 包裝函數():print("開始時間:2025-06-10 10:00")原函數()  # 調用原函數(看書)print("結束時間:2025-06-10 11:00")return 包裝函數@記錄時間  # 用裝飾器包裝函數
    def read_book():print("正在閱讀《Python入門》")read_book()  # 調用時會自動觸發裝飾器的「記錄時間」功能
    

    輸出:

    plaintext

    開始時間:2025-06-10 10:00
    正在閱讀《Python入門》
    結束時間:2025-06-10 11:00
    

2. 函數裝飾器的寫法:三步搭出「包裝流水線」

寫法模板(以 Python 為例)

?
  1. 定義裝飾器函數:接收原函數作為參數。
  2. 定義內部包裝函數:在原函數前后添加新功能。
  3. 返回包裝函數:用?@裝飾器名?語法糖應用到目標函數。
?

比喻拆解:包裝禮物的流水線

?

python

運行

# 1. 定義「包裝紙」函數(裝飾器)
def 包裝紙(禮物):  # 禮物=原函數# 2. 定義「包裝過程」函數(內部函數)def 包禮物():print("? 放上絲帶")       # 新增功能1禮物()                   # 調用原禮物(不修改原內容)print("🎀 貼上祝福卡片")  # 新增功能2# 3. 返回「包裝好的禮物」return 包禮物# 用裝飾器包裝「送書」函數
@包裝紙  # 等價于 send_book = 包裝紙(send_book)
def send_book():print("📚 送出《Python書》")# 調用包裝后的函數
send_book()
?

執行效果

?

plaintext

? 放上絲帶
📚 送出《Python書》
🎀 貼上祝福卡片

3. 注意內部函數的返回值:別讓禮物「消失在包裝里」

常見錯誤:如果內部函數不返回原函數的結果,原函數的返回值會丟失(就像把禮物放進盒子卻不裝進去,最后送出空盒子)。

?

比喻對比

?
  • 正確做法:包裝禮物時必須把「禮物本身」放進盒子,否則收禮人拿到的是空盒子。
  • 錯誤做法:包裝時只放包裝紙,沒放禮物,結果丟失了禮物。
?

代碼示例

?

python

運行

# ? 錯誤寫法:內部函數不返回原函數結果
def 錯誤裝飾器(原函數):def 包裝函數():print("開始裝飾")原函數()  # 調用原函數,但沒保存結果print("裝飾結束")return 包裝函數@錯誤裝飾器
def get_gift():return "鉆石戒指"  # 原函數返回一個值result = get_gift()
print(result)  # 輸出:None(原函數的返回值丟失了!)# ? 正確寫法:必須返回原函數的調用結果
def 正確裝飾器(原函數):def 包裝函數():print("開始裝飾")gift = 原函數()  # 保存原函數的返回值print("裝飾結束")return gift  # 返回原函數的結果return 包裝函數@正確裝飾器
def get_gift():return "鉆石戒指"result = get_gift()
print(result)  # 輸出:鉆石戒指(結果正確傳遞)

終極比喻總結:裝飾器是「函數的變裝皇后」

裝飾器要素生活比喻核心作用
原函數素顏的人原本的功能主體
裝飾器函數造型師負責給函數「化妝」(添加功能)
內部包裝函數化妝過程在原功能前后插入新操作
@裝飾器語法造型師的「魔法咒語」一鍵應用變裝效果
必須返回原結果化妝不能改變人的本質裝飾后必須保留原函數的返回值
?

通過「包裝禮物」的比喻,可以直觀理解裝飾器的「無侵入式增強」特性 —— 就像我們不會為了系蝴蝶結而拆開禮物盒,裝飾器也不會修改原函數的代碼,卻能讓函數「穿上新功能的外衣」,實現高效復用~ 🎁

另回答:

好的!我會用生活中的例子來比喻這三個知識點,盡量讓抽象的概念變得直觀~

1. 裝飾器的思想:進一步復用

知識點解釋
裝飾器是一種不修改原有函數代碼,卻能為其動態添加新功能的編程技巧。它的核心是 “復用代碼邏輯”,比如給多個函數統一添加日志記錄、權限校驗等功能,避免重復寫重復代碼。

比喻
就像給蛋糕加裝飾:

  • 蛋糕本身(原有函數)的配方(代碼)不需要改變,
  • 但可以通過裱花(裝飾器)給不同蛋糕(不同函數)加上奶油、水果(新功能),
  • 而且同一套裱花工具(裝飾器邏輯)可以重復用在多個蛋糕上,避免每次都重新設計裝飾。

場景舉例
比如多個函數都需要記錄執行時間,用裝飾器就像給每個函數 “貼” 一個計時器,不用每個函數里都寫一遍計時代碼。

2. 函數的裝飾器寫法

知識點解釋
裝飾器本質是一個高階函數(參數或返回值是函數的函數),寫法分兩步:

  1. 定義裝飾器函數:它接受一個函數(被裝飾的函數)作為參數,返回一個內部函數(包裹了原函數的新功能)。
  2. @裝飾器名語法糖給目標函數 “裝飾”。

比喻
就像做三明治:

  • 面包片 1(裝飾器外層函數):接受食材(原函數)作為參數,
  • 夾心菜肉(內部函數):在食材前后添加面包片(新功能),比如先抹醬(前置邏輯),再放食材(原函數執行),最后蓋另一片面包(后置邏輯),
  • 成品三明治(返回的內部函數):比原來的食材更豐富,但保留了食材本身的味道(原函數功能)。

代碼示例

python

# 定義裝飾器:給函數加“吃前洗手”和“吃完擦嘴”的邏輯
def sandwich_decorator(func):def wrapper():  # 內部函數,包裹原函數print("? 先洗手(前置邏輯)")func()       # 執行原函數(吃三明治)print("? 再擦嘴(后置邏輯)")return wrapper   # 返回包裹后的函數# 用@語法糖裝飾目標函數
@sandwich_decorator
def eat_sandwich():print("🍔 正在吃三明治(原函數邏輯)")# 調用裝飾后的函數
eat_sandwich()

輸出

plaintext

? 先洗手(前置邏輯)
🍔 正在吃三明治(原函數邏輯)
? 再擦嘴(后置邏輯)

3. 注意內部函數的返回值

知識點解釋
如果原函數有返回值(比如計算結果),裝飾器的內部函數必須顯式返回原函數的調用結果,否則調用裝飾后的函數會得到None(空值)。

比喻
就像送快遞:

  • 原函數是 “打包商品” 的函數,返回值是 “包裹里的商品”,
  • 裝飾器是 “貼快遞單” 的流程,如果貼單后不把包裹(返回值)交給快遞員(調用者),買家收到的就是空包裹(None)。

代碼示例

python

# 錯誤示范:內部函數不返回原函數結果
def bad_decorator(func):def wrapper():func()  # 執行原函數,但不返回結果return wrapper@bad_decorator
def add(a, b):return a + b  # 原函數有返回值result = add(1, 2)
print(result)  # 輸出:None(丟失了返回值!)

python

# 正確示范:內部函數返回原函數結果
def good_decorator(func):def wrapper(*args, **kwargs):  # 通用參數接收return func(*args, **kwargs)  # 必須返回原函數調用結果return wrapper@good_decorator
def add(a, b):return a + bresult = add(1, 2)
print(result)  # 輸出:3(正確保留返回值)

總結

  • 裝飾器思想:像給函數 “穿外套”,復用功能代碼,不修改原函數。
  • 寫法關鍵:裝飾器是高階函數,用@語法糖簡化調用,內部函數包裹原函數。
  • 返回值注意:內部函數必須 “接住” 原函數的返回值并返回,否則結果會 “丟失”。

如果還有疑問,可以隨時問我哦! 😊


代碼:

def logger(func):def wrapper(*args, **kwargs):print(f"調用函數: {func.__name__},參數: {args}, {kwargs}")result = func(*args, **kwargs)print(f"函數返回值: {result}")return resultreturn wrapper
@logger
def multiply(a, b):return a * b multiply(2, 3)

?另代碼:

def logger(func):def wrapper(*args, **kwargs):# 打印函數執行前的日志print(f"開始執行函數: {func.__name__}")print(f"位置參數: {args}")print(f"關鍵字參數: {kwargs}")# 執行原函數result = func(*args, **kwargs)# 打印函數執行后的日志print(f"函數 {func.__name__} 執行完畢")print(f"返回值: {result}")return resultreturn wrapper# 示例函數,用于測試裝飾器
@logger
def add_numbers(a, b):return a + b# 調用示例函數
add_numbers(3, 5)

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

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

相關文章

網傳西門子12億美元收購云原生工業軟件,云化PLM系統轉機在協同

近日,網傳西門子將以12億美元全現金交易收購云原生MES公司FlexFact,并整合其技術至Xcelerator工業軟件平臺。如果此次收購動作完成,將會成為西門子加速工業云轉型的標志性動作,背后的意義也極為深遠,不僅會直接響應競爭…

大模型筆記_檢索增強生成(RAG)

1. RAG的概念 RAG(Retrieval-Augmented Generation) 是一種結合 信息檢索(Retrieval)與文本生成(Generation)的模型架構,旨在通過動態引入外部知識庫或實時數據,提升大語言模型&…

Spring Security是如何完成身份認證的?

1. 用戶名和密碼被過濾器獲取到,封裝成 Authentication ,通常情況下是 UsernamePasswordAuthenticationToken 這個實現類。 2. AuthenticationManager 身份管理器負責驗證這個 Authentication 3. 認證成功后, AuthenticationManager 身份管理器返回一…

Python爬蟲實戰:研究xmltodict庫相關技術

1. 引言 1.1 研究背景與意義 氣象數據是環境研究、農業生產、城市規劃等領域的重要基礎。隨著互聯網技術的發展,越來越多的氣象數據以 XML 格式在網絡上公開。XML(可擴展標記語言)因其結構化和自描述性的特點,成為數據交換的標準格式之一。然而,這些數據通常分散在不同的…

中小企業無線局域網絡搭建與優化指南

1. 引言:無線網絡——驅動中國中小企業數字化轉型的引擎 無線網絡已成為現代企業運營的基礎設施,直接影響員工工作效率和客戶體驗。隨著Wi-Fi7技術的成熟和普及,中小企業網絡建設正迎來全新機遇。在數字經濟浪潮席卷全球的今天,無…

【已解決】python的kafka-python包連接kafka報認證失敗

先說原因:安裝python包的時候,多裝了一個kafka的包:kafka 1.3.5 我把py文件打包成二進制文件,在linux上執行就一直報認證失敗,后來確認登錄信息、認證方式沒有問題,把這個kafka包卸載…

傳輸層協議TCP(下)

上一篇https://blog.csdn.net/Small_entreprene/article/details/148193741?sharetypeblogdetail&sharerId148193741&sharereferPC&sharesourceSmall_entreprene&sharefrommp_from_link 接下來,我們來談論TCP具體的機制! 具體TCP機制 …

洛谷B3612 【深進1.例1】求區間和

題目描述 給定 n 個正整數組成的數列 a1?,a2?,?,an? 和 m 個區間 [li?,ri?],分別求這 m 個區間的區間和。 輸入格式 第一行,為一個正整數 n 。 第二行,為 n 個正整數 a1?,a2?,?,an? 第三行,為一個正整數 m 。 接下…

debian12 修改MariaDB數據庫存儲位置報錯

debian12 修改MariaDB數據庫存儲位置到home報錯 MariaDB 修改存儲路徑后啟動失敗問題解決 更改數據存儲位置 如果需要將數據存儲到其他位置(如更大的分區): 停止 MariaDB 服務: bash sudo systemctl stop mariadb 創建新目錄并設…

【評測】flux-dev文生圖模型初體驗

回到目錄 【評測】flux-dev文生圖模型初體驗 1. 安裝基礎環境 參考 modelscope的Flux.1-dev頁面 2. 使用tongyi寫提示詞 幫我用英文寫3個,文生圖片1024*1024的提示詞,準備用flux.dev生成用 [pic03] 3. 運行代碼 4090D滿載運行, 1min左…

PHP7+MySQL5.6 雪里開簡易預約制訪客管理系統V1.0

# PHP7MySQL5.6 雪里開簡易預約制訪客管理系統 V1.0 ## 簡介 本系統是一個基于PHP7和MySQL5.6的封閉校區訪客管理系統,用于管理學生訪客的申請、核銷流程。 導入的賬號預先提交訪客信息(預約制),無需審核,訪客提交匿名制訪客碼給門衛登記放行…

【深度學習:進階篇】--2.4.BN與神經網絡調優

學習目標 目標 知道常用的一些神經網絡超參數知道BN層的意義以及數學原理 應用 無 目錄 學習目標 1.神經網絡調優 1.1.調參技巧 1.2.運行 2.批標準化(Batch Normalization) 2.1.標準化公式 2.2.為什么可以優化簡單 2.3.BN總結 1.神經網絡調優 …

CMake指令: add_sub_directory以及工作流程

目錄 1.簡介 2.工作流程 3.示例場景 4.最佳實踐 5.注意事項 6.總結 相關鏈接 1.簡介 add_subdirectory 是 CMake 中用于添加子目錄參與構建的命令,允許將項目拆分為多個模塊或子項目,實現代碼的模塊化管理。 基本語法: add_subdirect…

【C++ 】智能指針:內存管理的 “自動導航儀”

目錄 一、引入 二、智能指針的兩大特性: 1、RAII 特點: 好處: 2、行為像指針 三、智能指針起初的缺陷:拷貝問題 四、幾種智能指針的介紹。 1、C98出現的智能指針——auto_ptr auto_ptr解決上述拷貝構造的問題&#xff1a…

Java多線程實現之線程池詳解

Java多線程實現之線程池詳解 一、線程池的基本概念1.1 為什么需要線程池1.2 線程池的核心思想 二、Java線程池的實現2.1 Executor框架2.2 ThreadPoolExecutor構造參數 三、常見線程池類型3.1 FixedThreadPool3.2 CachedThreadPool3.3 SingleThreadExecutor3.4 ScheduledThreadP…

解碼美元-黃金負相關:LSTM-Attention因果發現與黃金反彈推演

摘要:本文采用時間序列分析框架與自然語言處理(NLP)技術,對黃金與美元指數的負相關關系進行量化拆解。通過構建包含宏觀經濟因子、市場情緒指標及地緣風險的三維分析模型,揭示當前貴金屬市場的核心驅動邏輯&#xff0c…

Asp.Net Core SignalR導入數據

文章目錄 前言一、安裝包二、使用步驟1.實現SignalR Hub服務:2.實現CSV文件解析及數據導入服務3.控制器4.前端實現(vue) 三、關鍵技術點說明總結 前言 導入CSV文件中的數據到數據庫,使用CsvHelper解析CSV文件,SqlBulk…

Modern C++(四)聲明

4、聲明 聲明是將名字引入到cpp程序中,不是每條聲明都聲明實際的東西。定義是足以使該名字所標識的實體被使用的聲明。聲明包含以下幾種: 函數定義模板聲明模板顯式實例化模板顯式特化命名空間定義鏈接說明屬性聲明(C11)空聲明&…

目標檢測yolo算法

yolov5s: 從github官網下載yolov5的算法之后,配置好環境(pycharm安裝包-CSDN博客),再下載權重文件,比如默認的yolov5s.pt; 運行當前文件(detect.py),就能看…

一個超強的推理增強大模型,開源了,本地部署

大家好,我是 Ai 學習的老章 前幾天介紹了MOE 模型先驅 Mistral 開源的代碼 Agent 大模型——mistralai/Devstral-Small-2505 今天一起看看 Mistral 最新開源的推理大模型——Magistral Magistral 簡介 Mistral 公司推出了首個推理模型 Magistral 及自研可擴展強…