Python 装饰器详解:从入门到精通的 7 个实用案例

Python 装饰器详解:从入门到精通的 7 个实用案例

一、什么是装饰器

装饰器(Decorator)是 Python 中的一种高级特性,它允许你在不修改原函数代码的情况下,为函数添加额外的功能。简单来说,装饰器就是一个返回函数的函数。

二、基础语法

python 复制代码
def my_decorator(func):
    def wrapper():
        print("执行前")
        func()
        print("执行后")
    return wrapper

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

say_hello()
# 输出:
# 执行前
# Hello!
# 执行后

三、带参数的装饰器

python 复制代码
def repeat(n):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(n):
                func(*args, **kwargs)
        return wrapper
    return decorator

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

greet("World")

四、实用案例 1:日志记录

python 复制代码
import functools
import time

def logger(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"[LOG] 调用 {func.__name__}")
        result = func(*args, **kwargs)
        print(f"[LOG] {func.__name__} 完成")
        return result
    return wrapper

@logger
def add(a, b):
    return a + b

add(3, 5)

五、实用案例 2:性能计时

python 复制代码
def timer(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} 耗时:{end-start:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(1)

slow_function()

六、实用案例 3:权限验证

python 复制代码
def require_auth(func):
    def wrapper(user, *args, **kwargs):
        if not user.is_authenticated:
            raise PermissionError("未授权访问")
        return func(user, *args, **kwargs)
    return wrapper

@require_auth
def delete_account(user):
    print(f"删除用户 {user.name} 的账户")

七、实用案例 4:缓存装饰器

python 复制代码
def cache(func):
    cache_dict = {}
    @functools.wraps(func)
    def wrapper(*args):
        if args in cache_dict:
            print("命中缓存")
            return cache_dict[args]
        result = func(*args)
        cache_dict[args] = result
        return result
    return wrapper

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

print(fibonacci(10))

八、实用案例 5:重试机制

python 复制代码
import random

def retry(max_attempts=3):
    def decorator(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"重试 {i+1}/{max_attempts}")
            return None
        return wrapper
    return decorator

@retry(3)
def unstable_api():
    if random.random() < 0.7:
        raise ConnectionError("网络错误")
    return "成功"

九、实用案例 6:类型检查

python 复制代码
def type_check(*expected_types):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for arg, expected in zip(args, expected_types):
                if not isinstance(arg, expected):
                    raise TypeError(f"参数类型错误:期望 {expected}, 得到 {type(arg)}")
            return func(*args, **kwargs)
        return wrapper
    return decorator

@type_check(int, int)
def multiply(a, b):
    return a * b

multiply(5, 3)  # OK
# multiply("5", 3)  # TypeError

十、实用案例 7:类方法装饰器

python 复制代码
class MyClass:
    def __init__(self):
        self.count = 0
    
    def increment(func):
        def wrapper(self, *args, **kwargs):
            self.count += 1
            print(f"调用次数:{self.count}")
            return func(self, *args, **kwargs)
        return wrapper
    
    @increment
    def greet(self):
        print("Hello from MyClass!")

obj = MyClass()
obj.greet()
obj.greet()

总结

装饰器是 Python 中非常强大的工具,掌握它可以让你写出更优雅、更模块化的代码。以上 7 个案例涵盖了日志、性能监控、权限控制、缓存、重试、类型检查等常见场景,建议在实际项目中灵活运用。

相关推荐
2501_928945521 分钟前
命题GTFE-1:修正爱因斯坦场方程的张量形式推导
python
cfm_29142 分钟前
JVM对象逃逸分析深度详解
java·开发语言·jvm
SilentSamsara2 分钟前
LLM API 工程化:OpenAI/DeepSeek/国产模型统一调用层设计
开发语言·人工智能·python
weixin_523185327 分钟前
SimpleDateFormat为什么线程不安全?源码级解析与解决方案
java·开发语言·安全
Chase_______10 分钟前
【Java杂项】Java 中的 null:空指针、自动拆箱与集合边界详解
java·开发语言
j7~10 分钟前
【C++】STL--string类--拆析解剖string以及string类的底层详解(1)
开发语言·c++·ascii编码·string类·auto和范围for
Wonderful U12 分钟前
Python+Django实战|社区物业管理系统:业主档案、车位管理、物业费收缴、线上报修、投诉建议、园区公告、日常巡检
android·python·django
techdashen13 分钟前
Rust 项目管理动态 — 2026 年 2 月
开发语言·后端·rust
想吃火锅10059 小时前
【leetcode】405.数字转换为十六进制数js
开发语言·javascript·ecmascript
珺毅同学9 小时前
YOLO生成预测json标签迁移问题
python·yolo·json