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

Python裝飾器原理與實(shí)戰(zhàn)全解

 更新時(shí)間:2026年05月05日 11:31:25   作者:第一程序員  
這篇文章主要介紹了Python裝飾器原理與實(shí)戰(zhàn),裝飾器是Python中一種強(qiáng)大的特性,它允許我們以一種簡潔、優(yōu)雅的方式增強(qiáng)函數(shù)的功能,通過掌握裝飾器的高級(jí)應(yīng)用,我們可以編寫更加模塊化、可維護(hù)的代碼

1. 裝飾器基礎(chǔ)

裝飾器是 Python 中一種強(qiáng)大的特性,它允許我們?cè)诓恍薷脑瘮?shù)代碼的情況下,增強(qiáng)函數(shù)的功能。

def decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function call")
        result = func(*args, **kwargs)
        print("After function call")
        return result
    return wrapper
@decorator
def greet(name):
    print(f"Hello, {name}!")
# 調(diào)用被裝飾的函數(shù)
greet("Alice")

2. 帶參數(shù)的裝飾器

2.1 基本帶參裝飾器

def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for i in range(n):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator
@repeat(3)
def greet(name):
    print(f"Hello, {name}!")
greet("Alice")

2.2 裝飾器類

class Timer:
    def __init__(self, unit="seconds"):
        self.unit = unit
    def __call__(self, func):
        def wrapper(*args, **kwargs):
            import time
            start = time.time()
            result = func(*args, **kwargs)
            end = time.time()
            duration = end - start
            if self.unit == "milliseconds":
                duration *= 1000
            print(f"Function {func.__name__} took {duration:.2f} {self.unit}")
            return result
        return wrapper
@Timer(unit="milliseconds")
def slow_function():
    import time
    time.sleep(1)
    print("Function executed")
slow_function()

3. 高級(jí)裝飾器技巧

3.1 保留函數(shù)元數(shù)據(jù)

使用 functools.wraps 可以保留被裝飾函數(shù)的元數(shù)據(jù)。

import functools
def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        """Wrapper function"""
        print("Before function call")
        result = func(*args, **kwargs)
        print("After function call")
        return result
    return wrapper
@decorator
def greet(name):
    """Greet someone"""
    print(f"Hello, {name}!")
print(greet.__name__)  # 輸出: greet
print(greet.__doc__)   # 輸出: Greet someone

3.2 疊加裝飾器

多個(gè)裝飾器可以疊加使用,執(zhí)行順序是從下到上。

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1 before")
        result = func(*args, **kwargs)
        print("Decorator 1 after")
        return result
    return wrapper
def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2 before")
        result = func(*args, **kwargs)
        print("Decorator 2 after")
        return result
    return wrapper
@decorator1
@decorator2
def greet(name):
    print(f"Hello, {name}!")
greet("Alice")
# 輸出順序:
# Decorator 1 before
# Decorator 2 before
# Hello, Alice!
# Decorator 2 after
# Decorator 1 after

3.3 裝飾器工廠

裝飾器工廠是一個(gè)函數(shù),它返回一個(gè)裝飾器。

def create_decorator(prefix):
    def decorator(func):
        def wrapper(*args, **kwargs):
            print(f"{prefix}: Before function call")
            result = func(*args, **kwargs)
            print(f"{prefix}: After function call")
            return result
        return wrapper
    return decorator
@create_decorator("DEBUG")
def greet(name):
    print(f"Hello, {name}!")
greet("Alice")

4. 實(shí)際應(yīng)用場(chǎng)景

4.1 日志記錄

import functools
import logging
logging.basicConfig(level=logging.INFO)
def log(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        logging.info(f"Calling {func.__name__} with args: {args}, kwargs: {kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"{func.__name__} returned: {result}")
        return result
    return wrapper
@log
def add(a, b):
    return a + b
result = add(1, 2)
print(result)

4.2 緩存

import functools
def cache(func):
    cache_dict = {}
    @functools.wraps(func)
    def wrapper(*args):
        if args in cache_dict:
            return cache_dict[args]
        result = func(*args)
        cache_dict[args] = result
        return result
    return wrapper
@cache
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(30))  # 第一次計(jì)算較慢
print(fibonacci(30))  # 第二次使用緩存,速度很快

4.3 權(quán)限驗(yàn)證

import functools
def requires_permission(permission):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            # 假設(shè) current_user 是當(dāng)前登錄用戶
            current_user = {"permissions": ["read", "write"]}
            if permission not in current_user["permissions"]:
                raise PermissionError(f"User does not have {permission} permission")
            return func(*args, **kwargs)
        return wrapper
    return decorator
@requires_permission("write")
def create_post(title, content):
    print(f"Creating post: {title}")
    return {"title": title, "content": content}
@requires_permission("admin")
def delete_post(post_id):
    print(f"Deleting post: {post_id}")
    return True
create_post("Hello", "World")  # 成功
# delete_post(1)  # 拋出 PermissionError

4.4 性能分析

import functools
import time
def performance(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds")
        return result
    return wrapper
@performance
def slow_function():
    time.sleep(1)
    return "Done"
slow_function()

5. 最佳實(shí)踐

  1. 使用 functools.wraps:保留被裝飾函數(shù)的元數(shù)據(jù),如函數(shù)名、文檔字符串等。
  2. 保持裝飾器簡單:裝飾器應(yīng)該專注于單一功能,避免過于復(fù)雜。
  3. 使用參數(shù)化裝飾器:對(duì)于需要配置的裝飾器,使用參數(shù)化裝飾器可以提高靈活性。
  4. 注意裝飾器的執(zhí)行順序:當(dāng)使用多個(gè)裝飾器時(shí),注意它們的執(zhí)行順序。
  5. 測(cè)試裝飾器:確保裝飾器在各種情況下都能正常工作。
  6. 文檔化裝飾器:為裝飾器添加文檔字符串,說明其功能和用法。
  7. 避免修改函數(shù)簽名:裝飾器應(yīng)該保持函數(shù)的簽名不變。

6. 總結(jié)

裝飾器是 Python 中一種強(qiáng)大的特性,它允許我們以一種簡潔、優(yōu)雅的方式增強(qiáng)函數(shù)的功能。通過掌握裝飾器的高級(jí)應(yīng)用,我們可以編寫更加模塊化、可維護(hù)的代碼。

在實(shí)際應(yīng)用中,裝飾器可以用于日志記錄、緩存、權(quán)限驗(yàn)證、性能分析等多種場(chǎng)景,大大提高代碼的復(fù)用性和可維護(hù)性。

希望本文對(duì)你理解和應(yīng)用 Python 裝飾器有所幫助!

以上就是Python裝飾器原理與實(shí)戰(zhàn)全解的詳細(xì)內(nèi)容,更多關(guān)于Python裝飾器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 基于python實(shí)現(xiàn)MUI區(qū)域滾動(dòng)

    基于python實(shí)現(xiàn)MUI區(qū)域滾動(dòng)

    這篇文章主要介紹的是python實(shí)現(xiàn)MUI區(qū)域滾動(dòng),MUI提供了區(qū)域滾動(dòng)的組件,使用時(shí)遵循DOM結(jié)構(gòu)就可以,下面來看看文章具體的實(shí)現(xiàn)內(nèi)容,需要的朋友可以參考一下
    2021-11-11
  • 使用Python實(shí)現(xiàn)Markdown轉(zhuǎn)Word工具

    使用Python實(shí)現(xiàn)Markdown轉(zhuǎn)Word工具

    在日常工作中,我們經(jīng)常需要將Markdown格式的文檔轉(zhuǎn)換為Word格式,本文將介紹如何使用Python實(shí)現(xiàn)一個(gè)功能強(qiáng)大,使用簡單的Markdown轉(zhuǎn)Word轉(zhuǎn)換工具,需要的可以參考一下
    2025-05-05
  • python模塊之re正則表達(dá)式詳解

    python模塊之re正則表達(dá)式詳解

    正則表達(dá)式是一種小型的、高度專業(yè)化的編程語言,并不是python中特有的,是許多編程語言中基礎(chǔ)而又重要的一部分。在python中,主要通過re模塊來實(shí)現(xiàn)。這篇文章主要介紹了python模塊之re正則表達(dá)式詳解,需要的朋友可以參考下
    2017-02-02
  • Python定時(shí)任務(wù)工具之APScheduler使用方式

    Python定時(shí)任務(wù)工具之APScheduler使用方式

    APScheduler (advanceded python scheduler)是一款Python開發(fā)的定時(shí)任務(wù)工具。這篇文章主要介紹了Python定時(shí)任務(wù)工具--APScheduler的使用方式,需要的朋友可以參考下
    2019-07-07
  • python網(wǎng)絡(luò)編程之多線程同時(shí)接受和發(fā)送

    python網(wǎng)絡(luò)編程之多線程同時(shí)接受和發(fā)送

    這篇文章主要為大家詳細(xì)介紹了python網(wǎng)絡(luò)編程之多線程同時(shí)接受和發(fā)送,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • 詳解Open Folder as PyCharm Project怎么添加的方法

    詳解Open Folder as PyCharm Project怎么添加的方法

    這篇文章主要介紹了詳解Open Folder as PyCharm Project怎么添加的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Python接收手機(jī)短信的代碼整理

    Python接收手機(jī)短信的代碼整理

    在本篇文章里小編給大家整理的是一篇關(guān)于Python接收手機(jī)短信的代碼內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-08-08
  • python對(duì)RabbitMQ的簡單入門使用教程

    python對(duì)RabbitMQ的簡單入門使用教程

    RabbitMq是實(shí)現(xiàn)了高級(jí)消息隊(duì)列協(xié)議(AMQP)的開源消息代理中間件,下面這篇文章主要給大家介紹了關(guān)于python對(duì)RabbitMQ的簡單入門使用,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • python串口如何讀取byte類型數(shù)據(jù)并訪問

    python串口如何讀取byte類型數(shù)據(jù)并訪問

    這篇文章主要介紹了python串口如何讀取byte類型數(shù)據(jù)并訪問方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 用Python的Tornado框架結(jié)合memcached頁面改善博客性能

    用Python的Tornado框架結(jié)合memcached頁面改善博客性能

    這篇文章主要介紹了用Python的Tornado框架結(jié)合memcached頁面改善vLog性能,主要使用到了緩存來提升性能,需要的朋友可以參考下
    2015-04-04

最新評(píng)論

尚志市| 繁昌县| 许昌市| 聊城市| 醴陵市| 桐柏县| 印江| 咸宁市| 页游| 舞钢市| 岱山县| 广宗县| 阳新县| 万源市| 山丹县| 丰台区| 包头市| 卓尼县| 临澧县| 仁怀市| 茂名市| 常州市| 杭锦旗| 务川| 威远县| 获嘉县| 绥滨县| 中超| 长武县| 永平县| 清丰县| 沧州市| 海口市| 广水市| 南宫市| 普格县| 济阳县| 朝阳区| 平果县| 濮阳县| 共和县|