最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python高階精講之閉包與裝飾器徹底吃透(零基礎(chǔ)看懂+實(shí)戰(zhàn)源碼)

 更新時(shí)間:2026年06月28日 10:13:00   作者:我材不敲代碼  
本文詳細(xì)解析Python閉包與裝飾器,從基礎(chǔ)到實(shí)戰(zhàn),覆蓋閉包原理、裝飾器本質(zhì)、帶參裝飾器、企業(yè)級(jí)實(shí)戰(zhàn)場(chǎng)景等,零基礎(chǔ)也能快速掌握,希望對(duì)大家有所幫助

前言

很多Python開(kāi)發(fā)者學(xué)了很久,依然看不懂裝飾器、不會(huì)手寫(xiě)裝飾器、不懂閉包原理。

但閉包和裝飾器是Python進(jìn)階分水嶺:源碼、框架(Flask/Django)、緩存、日志、接口鑒權(quán)、性能統(tǒng)計(jì),底層全部依賴這套語(yǔ)法。

本文用最通俗的語(yǔ)言+分步拆解+完整實(shí)戰(zhàn)源碼,從零帶你吃透:函數(shù)進(jìn)階 → 閉包原理 → 裝飾器基礎(chǔ) → 有參裝飾器 → 多層裝飾器 → 企業(yè)級(jí)實(shí)戰(zhàn)場(chǎng)景,零基礎(chǔ)也能一次性學(xué)懂。

01 前置基礎(chǔ):函數(shù)是一等公民

Python中函數(shù)是一等對(duì)象(一等公民),擁有三個(gè)核心特性,這是閉包、裝飾器能實(shí)現(xiàn)的根本:

  • 函數(shù)可以賦值給變量
  • 函數(shù)可以作為參數(shù)、返回值
  • 函數(shù)可以嵌套定義(內(nèi)部函數(shù))

基礎(chǔ)示例

# 1. 函數(shù)賦值給變量
def hello():
    print("Hello Python")

f = hello
f()

# 2. 函數(shù)作為返回值
def outer():
    def inner():
        print("內(nèi)部函數(shù)執(zhí)行")
    return inner

res = outer()
res()

核心總結(jié):正因?yàn)楹瘮?shù)可以嵌套、可以返回,才誕生了閉包。

02 閉包詳解:定義、條件、原理

2.1 閉包的必備三要素

同時(shí)滿足以下3點(diǎn),就是閉包(Closure)

  • 函數(shù)嵌套(外層函數(shù)+內(nèi)層函數(shù))
  • 內(nèi)層函數(shù)引用外層函數(shù)的局部變量
  • 外層函數(shù)返回內(nèi)層函數(shù)

2.2 閉包實(shí)戰(zhàn)代碼

def outer(num):
    # 外層局部變量
    def inner():
        # 內(nèi)層引用外層變量
        print(f"傳入數(shù)值:{num}")
    return inner

# 接收內(nèi)層函數(shù)
func = outer(100)
# 調(diào)用內(nèi)層函數(shù)
func()

2.3 閉包核心特性(重點(diǎn))

正常函數(shù)執(zhí)行結(jié)束后,局部變量會(huì)被銷毀釋放。

閉包會(huì)保留外層函數(shù)的局部變量,不會(huì)被GC回收,實(shí)現(xiàn)了數(shù)據(jù)常駐、狀態(tài)保存

2.4 閉包經(jīng)典場(chǎng)景:計(jì)數(shù)器

def count_factory():
    cnt = 0
    def counter():
        nonlocal cnt
        cnt += 1
        print(f"當(dāng)前計(jì)數(shù):{cnt}")
    return counter

c1 = count_factory()
c1()  # 1
c1()  # 2
c1()  # 3

知識(shí)點(diǎn)nonlocal 關(guān)鍵字,用于內(nèi)層函數(shù)修改外層嵌套函數(shù)的局部變量。

03 裝飾器本質(zhì):基于閉包的語(yǔ)法糖

3.1 核心認(rèn)知

裝飾器 = 高階閉包 + 語(yǔ)法糖

裝飾器的核心作用:在不修改原函數(shù)代碼、不修改原函數(shù)調(diào)用方式的前提下,給函數(shù)新增功能。

這就是設(shè)計(jì)模式中的開(kāi)閉原則:對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。

3.2 裝飾器解決的問(wèn)題

  • 避免重復(fù)代碼(日志、計(jì)時(shí)、鑒權(quán)通用邏輯復(fù)用)
  • 業(yè)務(wù)代碼與通用工具代碼解耦
  • 統(tǒng)一項(xiàng)目規(guī)范,便于維護(hù)迭代

04 手寫(xiě)無(wú)參裝飾器:日志統(tǒng)計(jì)實(shí)戰(zhàn)

需求:給任意函數(shù)添加執(zhí)行日志、執(zhí)行耗時(shí)統(tǒng)計(jì)

4.1 原生閉包寫(xiě)法(理解底層)

import time

def timer_decorator(func):
    # 通用裝飾器,接收任意參數(shù)
    def wrapper(*args, **kwargs):
        start = time.time()
        # 執(zhí)行原函數(shù)
        res = func(*args, **kwargs)
        end = time.time()
        print(f"函數(shù)【{func.__name__}】執(zhí)行耗時(shí):{end - start:.4f}s")
        # 返回原函數(shù)結(jié)果
        return res
    return wrapper

# 測(cè)試函數(shù)
@timer_decorator
def calc_sum(n):
    s = 0
    for i in range(n):
        s += i
    return s

calc_sum(100000)

4.2 裝飾器執(zhí)行流程拆解

  • @timer_decorator 裝飾器加載,等價(jià)于 calc_sum = timer_decorator(calc_sum)
  • 調(diào)用 calc_sum() 實(shí)際執(zhí)行的是內(nèi)部包裝函數(shù) wrapper()
  • wrapper執(zhí)行前置邏輯 → 執(zhí)行原函數(shù) → 后置邏輯 → 返回結(jié)果

4.3 解決函數(shù)信息覆蓋問(wèn)題

直接使用裝飾器會(huì)導(dǎo)致原函數(shù)的函數(shù)名、文檔注釋被wrapper覆蓋,需要 functools.wraps 修復(fù):

import time
from functools import wraps

def timer_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print(f"函數(shù)【{func.__name__}】執(zhí)行耗時(shí):{end - start:.4f}s")
        return res
    return wrapper

05 進(jìn)階:帶參數(shù)裝飾器 + 多層裝飾器

5.1 帶參數(shù)裝飾器

普通裝飾器只能接收函數(shù)參數(shù),帶參裝飾器可以自定義配置參數(shù),靈活性更高。

需求:自定義日志等級(jí),控制是否打印日志

from functools import wraps

def log_decorator(switch=True):
    # 外層接收裝飾器參數(shù)
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            if switch:
                print(f"【日志】函數(shù){func.__name__}開(kāi)始執(zhí)行")
            res = func(*args, **kwargs)
            return res
        return wrapper
    return decorator

# 開(kāi)啟日志
@log_decorator(switch=True)
def test_func():
    print("業(yè)務(wù)邏輯執(zhí)行")

test_func()

5.2 多層裝飾器疊加執(zhí)行順序

加載順序:自下而上執(zhí)行順序:自上而下

口訣:先裝飾的后執(zhí)行,后裝飾的先執(zhí)行

from functools import wraps

def deco1(func):
    @wraps(func)
    def wrapper():
        print("deco1 前置")
        func()
        print("deco1 后置")
    return wrapper

def deco2(func):
    @wraps(func)
    def wrapper():
        print("deco2 前置")
        func()
        print("deco2 后置")
    return wrapper

@deco1
@deco2
def hello():
    print("核心業(yè)務(wù)執(zhí)行")

hello()

06 企業(yè)級(jí)實(shí)戰(zhàn)三大裝飾器(可直接復(fù)用)

6.1 接口鑒權(quán)裝飾器

from functools import wraps

def login_auth(func):
    @wraps(func)
    def wrapper(user_token, *args, **kwargs):
        # 模擬鑒權(quán)邏輯
        if not user_token:
            return {"code": 401, "msg": "未登錄,權(quán)限不足"}
        return func(user_token, *args, **kwargs)
    return wrapper

# 模擬接口
@login_auth
def get_user_info(token):
    return {"code": 200, "data": "用戶信息數(shù)據(jù)"}

print(get_user_info(""))

6.2 簡(jiǎn)易緩存裝飾器(避免重復(fù)計(jì)算)

from functools import wraps

def cache_decorator(func):
    cache = {}
    @wraps(func)
    def wrapper(*args):
        if args not in cache:
            cache[args] = func(*args)
        return cache[args]
    return wrapper

@cache_decorator
def fib(n):
    if n <= 2:
        return 1
    return fib(n-1) + fib(n-2)

print(fib(30))  # 首次計(jì)算,后續(xù)直接讀取緩存

6.3 異常捕獲裝飾器(統(tǒng)一異常處理)

from functools import wraps

def exception_catch(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as e:
            print(f"【函數(shù)異?!縶func.__name__}執(zhí)行失?。簕str(e)}")
            return None
    return wrapper

@exception_catch
def divide(a, b):
    return a / b

divide(10, 0)

07 面試高頻真題(必背)

Q1:什么是閉包?閉包的作用和缺點(diǎn)?

答:

閉包是嵌套函數(shù)中,內(nèi)層函數(shù)引用外層局部變量、外層返回內(nèi)層函數(shù)的代碼結(jié)構(gòu)。

作用:保存函數(shù)執(zhí)行狀態(tài)、實(shí)現(xiàn)數(shù)據(jù)常駐、簡(jiǎn)化代碼、實(shí)現(xiàn)裝飾器。

缺點(diǎn):外層變量常駐內(nèi)存無(wú)法釋放,長(zhǎng)期使用會(huì)造成內(nèi)存泄漏

Q2:裝飾器的原理是什么?為什么不修改原代碼?

裝飾器基于閉包+高階函數(shù)實(shí)現(xiàn),通過(guò)包裝原函數(shù),在函數(shù)執(zhí)行前后擴(kuò)展邏輯,符合開(kāi)閉原則,實(shí)現(xiàn)業(yè)務(wù)與通用邏輯解耦。

Q3:wraps裝飾器的作用?

修復(fù)裝飾器導(dǎo)致的原函數(shù)信息丟失問(wèn)題,保留原函數(shù)的 __name__、文檔注釋等屬性。

Q4:多層裝飾器的執(zhí)行順序?

加載自下而上,執(zhí)行自上而下,先裝飾的函數(shù)最后執(zhí)行后置邏輯。

到此這篇關(guān)于Python高階精講之閉包與裝飾器徹底吃透(零基礎(chǔ)看懂+實(shí)戰(zhàn)源碼)的文章就介紹到這了,更多相關(guān)Python閉包與裝飾器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文詳解Python中PO模式的設(shè)計(jì)與實(shí)現(xiàn)

    一文詳解Python中PO模式的設(shè)計(jì)與實(shí)現(xiàn)

    在使用 Python 進(jìn)行編碼的時(shí)候,會(huì)使用自身自帶的編碼設(shè)計(jì)格式,比如說(shuō)最常見(jiàn)的單例模式等。本文將為大家介紹PageObject自動(dòng)化設(shè)計(jì)模式(PO模式)的設(shè)計(jì)與實(shí)現(xiàn),感興趣的可以了解一下
    2022-06-06
  • Python錯(cuò)誤和異??偨Y(jié)詳細(xì)

    Python錯(cuò)誤和異??偨Y(jié)詳細(xì)

    本文詳細(xì)且清晰地講解了Python中錯(cuò)誤和異常的概念及其處理方式,通過(guò)具體案例展示try...except、try...finally、with...等句式的具體用法,期望能幫助到對(duì)此感到迷惑的初學(xué)者
    2021-10-10
  • 使用Python實(shí)現(xiàn)將HTML內(nèi)容格式插入Word文檔

    使用Python實(shí)現(xiàn)將HTML內(nèi)容格式插入Word文檔

    在日常開(kāi)發(fā)和業(yè)務(wù)流程中,我們經(jīng)常需要生成包含復(fù)雜格式和動(dòng)態(tài)內(nèi)容的Word文檔,本文將介紹如何使用Python實(shí)現(xiàn)將HTML內(nèi)容格式插入Word文檔,感興趣的小伙伴可以了解下
    2026-01-01
  • Python 串口讀寫(xiě)的實(shí)現(xiàn)方法

    Python 串口讀寫(xiě)的實(shí)現(xiàn)方法

    今天小編就為大家分享一篇Python 串口讀寫(xiě)的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-06-06
  • python MultipartEncoder傳輸zip文件實(shí)例

    python MultipartEncoder傳輸zip文件實(shí)例

    這篇文章主要介紹了python MultipartEncoder傳輸zip文件實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-04-04
  • opencv圖片處理常見(jiàn)操作方法總結(jié)

    opencv圖片處理常見(jiàn)操作方法總結(jié)

    這篇文章主要介紹了opencv圖片處理常見(jiàn)操作方法的相關(guān)資料,通過(guò)代碼示例,展示了如何對(duì)圖片進(jìn)行這些操作,并解釋了圖片在計(jì)算機(jī)中以數(shù)組形式存儲(chǔ)的原理,需要的朋友可以參考下
    2026-01-01
  • Python實(shí)現(xiàn)語(yǔ)音啟動(dòng)電腦應(yīng)用程序

    Python實(shí)現(xiàn)語(yǔ)音啟動(dòng)電腦應(yīng)用程序

    這篇文章主要為大家詳細(xì)介紹了如何使用Python實(shí)現(xiàn)語(yǔ)音啟動(dòng)電腦應(yīng)用程序功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一學(xué)習(xí)一下
    2025-03-03
  • Python繪圖實(shí)現(xiàn)顯示中文

    Python繪圖實(shí)現(xiàn)顯示中文

    今天小編就為大家分享一篇Python繪圖實(shí)現(xiàn)顯示中文,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-12-12
  • pandas 強(qiáng)制類型轉(zhuǎn)換 df.astype實(shí)例

    pandas 強(qiáng)制類型轉(zhuǎn)換 df.astype實(shí)例

    這篇文章主要介紹了pandas 強(qiáng)制類型轉(zhuǎn)換 df.astype實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-04-04
  • Flask類視圖的基本用法及高級(jí)技巧

    Flask類視圖的基本用法及高級(jí)技巧

    Flask的類視圖提供了一種強(qiáng)大而靈活的方式來(lái)構(gòu)建Web應(yīng)用的業(yè)務(wù)邏輯,本文主要介紹了Flask類視圖的基本用法及高級(jí)技巧,感興趣的可以了解一下
    2024-01-01

最新評(píng)論

荣昌县| 澄城县| 马边| 象州县| 时尚| 沈丘县| 东安县| 乌拉特前旗| 澄迈县| 黄龙县| 汉沽区| 隆子县| 布尔津县| 柳州市| 葵青区| 蒙城县| 马公市| 鄯善县| 奎屯市| 通许县| 高淳县| 浮山县| 棋牌| 白河县| 洪泽县| 惠安县| 泸定县| 肇东市| 东乡| 井研县| 阿拉尔市| 襄城县| 平遥县| 潍坊市| 大港区| 康乐县| 武鸣县| 呈贡县| 涪陵区| 上思县| 麻阳|