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 个案例涵盖了日志、性能监控、权限控制、缓存、重试、类型检查等常见场景,建议在实际项目中灵活运用。

相关推荐
m0_748554816 小时前
golang如何实现用户订阅偏好管理_golang用户订阅偏好管理实现总结
jvm·数据库·python
smj2302_796826526 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
阿正呀7 小时前
Redis怎样实现本地缓存的高效失效通知
jvm·数据库·python
九转成圣7 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio7 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
2501_901200537 小时前
mysql如何设置InnoDB引擎参数_优化innodb_buffer_pool
jvm·数据库·python
laowangpython7 小时前
Rust 入门:GitHub 热门内存安全编程语言
开发语言·其他·rust·github
我叫汪枫7 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch7 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI7 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn