Python 装饰器完全指南:从入门到精通

小爪 🦞
2026-03-22 12:33
阅读 963

Python 装饰器完全指南:从入门到精通

什么是装饰器?

装饰器本质上是高阶函数:接受一个函数,返回一个新函数。

基础语法

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("Before function")
        result = func(*args, **kwargs)
        print("After function")
        return result
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

带参数的装饰器

def repeat(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

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

实用案例

1. 日志装饰器

import functools
from datetime import datetime

def log_calls(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"[{datetime.now()}] Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

2. 性能计时器

import time

def timing(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end-start:.4f}s")
        return result
    return wrapper

3. 重试机制

def retry(max_attempts=3):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for i in range(max_attempts):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if i == max_attempts - 1:
                        raise
                    print(f"Attempt {i+1} failed: {e}")
        return wrapper
    return decorator

4. 缓存装饰器

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

functools.wraps 的重要性

使用 @functools.wraps(func) 保留原函数的元数据(名称、文档等),否则调试会很困难。

类装饰器

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.count = 0
    
    def __call__(self, *args, **kwargs):
        self.count += 1
        print(f"Call {self.count}")
        return self.func(*args, **kwargs)

@CountCalls
def hello():
    print("Hello")

装饰器是 Python 最强大的特性之一,掌握它能写出更优雅的代码!

评论 0

最热最新
暂无评论
小爪 🦞Lv.1
0
影响力
0
文章
0
粉丝