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

從入門到封裝通用詳解Python裝飾器實戰(zhàn)指南

 更新時間:2026年01月22日 15:58:34   作者:站大爺IP  
這篇文章主要介紹了為大家詳細(xì)介紹了Python中裝飾器使用的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、裝飾器初體驗:給函數(shù)穿"外套"

想象你有一件普通白T恤(原始函數(shù)),現(xiàn)在想給它加上圖案(額外功能)卻不改變衣服本身。Python裝飾器就像這件"魔法外套",能動態(tài)為函數(shù)添加功能而不修改原代碼。

1.1 最簡單的裝飾器

def simple_decorator(func):
    def wrapper():
        print("外套前襟:添加日志")
        func()
        print("外套后背:記錄耗時")
    return wrapper

@simple_decorator
def say_hello():
    print("Hello World!")

say_hello()

輸出結(jié)果:

外套前襟:添加日志
Hello World!
外套后背:記錄耗時

這個例子展示了裝飾器的核心機制:@simple_decorator相當(dāng)于say_hello = simple_decorator(say_hello),將原函數(shù)包裹在wrapper中。

1.2 處理帶參數(shù)的函數(shù)

當(dāng)被裝飾函數(shù)需要參數(shù)時,用*args**kwargs實現(xiàn)萬能適配:

def param_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"準(zhǔn)備調(diào)用{func.__name__},參數(shù):{args}, {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@param_decorator
def add(a, b, c=0):
    return a + b + c

print(add(1, 2, c=3))  # 輸出:準(zhǔn)備調(diào)用add,參數(shù):(1, 2), {'c': 3} \n 6

二、裝飾器進(jìn)階:解決三大痛點

2.1 保留函數(shù)元信息

直接使用裝飾器會丟失原函數(shù)的__name__、__doc__等信息,用functools.wraps修復(fù):

from functools import wraps

def safe_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        """這是包裝函數(shù)的文檔"""
        print("安全檢查通過")
        return func(*args, **kwargs)
    return wrapper

@safe_decorator
def calculate(x):
    """計算平方"""
    return x ** 2

print(calculate.__name__)  # 輸出:calculate(而非wrapper)
print(calculate.__doc__)   # 輸出:計算平方(而非包裝函數(shù)的文檔)

2.2 帶參數(shù)的裝飾器

當(dāng)需要為不同函數(shù)配置不同參數(shù)時(如日志級別、緩存時間),使用三層嵌套結(jié)構(gòu):

def configurable_decorator(level="INFO"):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            print(f"[{level}] 調(diào)用函數(shù): {func.__name__}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@configurable_decorator(level="DEBUG")
def fetch_data():
    return "數(shù)據(jù)獲取成功"

fetch_data()  # 輸出:[DEBUG] 調(diào)用函數(shù): fetch_data

2.3 多個裝飾器疊加

裝飾器執(zhí)行順序遵循"從下往上裝飾,從上往下執(zhí)行"原則:

def decor1(func):
    def wrapper():
        print("裝飾器1前")
        func()
        print("裝飾器1后")
    return wrapper

def decor2(func):
    def wrapper():
        print("裝飾器2前")
        func()
        print("裝飾器2后")
    return wrapper

@decor1
@decor2
def target():
    print("目標(biāo)函數(shù)執(zhí)行")

target()
"""
輸出:
裝飾器1前
裝飾器2前
目標(biāo)函數(shù)執(zhí)行
裝飾器2后
裝飾器1后
"""

三、實戰(zhàn)場景:打造企業(yè)級工具庫

3.1 性能監(jiān)控裝飾器

自動統(tǒng)計函數(shù)執(zhí)行時間并生成可視化報告:

import time
from functools import wraps

def performance_monitor(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.perf_counter()
        result = func(*args, **kwargs)
        duration = time.perf_counter() - start
        
        # 實際項目中可集成Prometheus等監(jiān)控系統(tǒng)
        print(f"?? {func.__name__} 執(zhí)行耗時: {duration:.4f}秒")
        return result
    return wrapper

@performance_monitor
def complex_calculation(n):
    return sum(i*i for i in range(n))

complex_calculation(1000000)  # 輸出:?? complex_calculation 執(zhí)行耗時: 0.1234秒

3.2 緩存裝飾器(Memoization)

對重復(fù)計算結(jié)果進(jìn)行緩存,特別適合遞歸函數(shù):

def cache_decorator(func):
    cache = {}
    @wraps(func)
    def wrapper(n):
        if n not in cache:
            cache[n] = func(n)
            print(f"?? 緩存命中缺失,計算并存儲結(jié)果 for {n}")
        else:
            print(f"?? 緩存命中 for {n}")
        return cache[n]
    return wrapper

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

print(fibonacci(10))  # 第二次調(diào)用fibonacci(5)等會直接從緩存讀取

3.3 權(quán)限驗證裝飾器

在Web開發(fā)中驗證用戶權(quán)限的經(jīng)典實現(xiàn):

def role_required(required_role):
    def decorator(func):
        @wraps(func)
        def wrapper(user, *args, **kwargs):
            if user.get("role") != required_role:
                raise PermissionError(f"需要{required_role}權(quán)限")
            return func(user, *args, **kwargs)
        return wrapper
    return decorator

# 測試用例
admin = {"role": "admin", "name": "Alice"}
guest = {"role": "guest", "name": "Bob"}

@role_required("admin")
def delete_user(user, user_id):
    print(f"{user['name']} 刪除了用戶 {user_id}")

try:
    delete_user(guest, 123)  # 拋出PermissionError
except PermissionError as e:
    print(e)  # 輸出:需要admin權(quán)限

四、高級技巧:裝飾器工廠與類裝飾器

4.1 動態(tài)配置的裝飾器工廠

根據(jù)運行時參數(shù)生成不同行為的裝飾器:

def retry_decorator(max_attempts=3, delay=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if attempt == max_attempts - 1:
                        raise
                    print(f"?? 嘗試 {attempt+1} 失敗,{delay}秒后重試...")
                    time.sleep(delay)
        return wrapper
    return decorator

@retry_decorator(max_attempts=5, delay=2)
def unstable_api_call():
    import random
    if random.random() < 0.7:
        raise ConnectionError("模擬網(wǎng)絡(luò)故障")
    return "成功獲取數(shù)據(jù)"

print(unstable_api_call())  # 可能需要多次重試

4.2 類裝飾器實現(xiàn)

當(dāng)需要維護(hù)狀態(tài)時,類裝飾器比函數(shù)更合適:

class CallCounter:
    def __init__(self, func):
        self.func = func
        self.count = 0
        
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"?? 函數(shù) {self.func.__name__} 已被調(diào)用 {self.count} 次")
        return self.func(*args, **kwargs)

@CallCounter
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")  # 輸出:?? 函數(shù) greet 已被調(diào)用 1次 \n Hello, Alice!
greet("Bob")    # 輸出:?? 函數(shù) greet 已被調(diào)用 2次 \n Hello, Bob!

五、企業(yè)級封裝:通用工具庫設(shè)計

將常用裝飾器封裝成可配置的Python包:

my_decorators/
├── __init__.py
├── core.py          # 基礎(chǔ)裝飾器實現(xiàn)
├── config.py        # 默認(rèn)配置
└── utils.py         # 輔助工具

core.py示例

from functools import wraps
import time
from .config import DEFAULT_CACHE_SIZE

def timing(func):
    """基礎(chǔ)性能監(jiān)控裝飾器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"?? {func.__name__} executed in {time.time()-start:.4f}s")
        return result
    return wrapper

def cached(max_size=DEFAULT_CACHE_SIZE):
    """可配置大小的緩存裝飾器"""
    cache = {}
    def decorator(func):
        @wraps(func)
        def wrapper(*args):
            if args in cache:
                return cache[args]
            result = func(*args)
            if len(cache) >= max_size:
                cache.popitem()  # 簡單LRU實現(xiàn)
            cache[args] = result
            return result
        return wrapper
    return decorator

使用示例

from my_decorators.core import timing, cached

@timing
@cached(max_size=100)
def expensive_computation(x):
    return sum(i*i for i in range(x))

print(expensive_computation(10000))  # 首次計算較慢
print(expensive_computation(10000))  # 第二次直接從緩存讀取

六、最佳實踐與避坑指南

性能考量:裝飾器中的操作會影響所有被裝飾函數(shù),避免在wrapper中做耗時操作

異常處理:確保裝飾器正確傳播異常,避免靜默失敗

文檔規(guī)范:為裝飾器編寫清晰的docstring,說明其行為和參數(shù)

測試覆蓋:特別測試裝飾器疊加、參數(shù)傳遞等邊界情況

類型提示:使用Python 3.5+的類型注解提升可維護(hù)性:

from typing import Callable, Any, TypeVar

F = TypeVar('F', bound=Callable[..., Any])

def type_safe_decorator(func: F) -> F:
    @wraps(func)
    def wrapper(*args, **kwargs) -> Any:
        # 類型安全的實現(xiàn)
        return func(*args, **kwargs)
    return wrapper  # type: ignore[return-value]

七、總結(jié)與展望

裝飾器作為Python最強大的特性之一,其應(yīng)用場景遠(yuǎn)不止于此。隨著異步編程的普及,async裝飾器、基于描述符的更復(fù)雜裝飾器等高級用法正在涌現(xiàn)。掌握裝飾器的核心思想——"在不修改原函數(shù)的情況下擴展功能",將使你的代碼更加優(yōu)雅、可維護(hù)且易于擴展。

建議從簡單場景開始實踐,逐步嘗試封裝自己的裝飾器工具庫。記?。汉玫难b飾器應(yīng)該像空氣一樣存在——使用時感受不到它的存在,但離開它代碼將變得笨重不堪。

到此這篇關(guān)于從入門到封裝通用詳解Python裝飾器實戰(zhàn)指南的文章就介紹到這了,更多相關(guān)Python裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

蒙阴县| 萨迦县| 阜阳市| 永德县| 扎赉特旗| 长武县| 伊川县| 马鞍山市| 民权县| 金坛市| 澜沧| 定州市| 乐东| 丹寨县| 兴化市| 门源| 南澳县| 民乐县| 九龙城区| 海原县| 洛扎县| 东平县| 闽侯县| 仁化县| 芦溪县| 府谷县| 安多县| 乐业县| 沧州市| 福泉市| 彭州市| 和龙市| 太原市| 阿城市| 阆中市| 绵阳市| 皋兰县| 榆社县| 镇赉县| 内丘县| 错那县|