Python装饰器:让代码优雅如诗的艺术

一、初识装饰器:代码世界的"俄罗斯套娃"

在Python的魔法世界里,装饰器(Decorator)就像代码界的俄罗斯套娃,它允许我们在不修改原函数代码的情况下,为函数动态添加新功能。这种"开闭原则"的完美实践,让我们的代码既保持了简洁性,又获得了强大的扩展能力。

def simple_decorator(func):
    def wrapper():
        print("函数执行前")
        func()
        print("函数执行后")
    return wrapper

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

say_hello()

当这段代码运行时,你会看到:

函数执行前
Hello World!
函数执行后

二、装饰器的四大实战场景

1. 性能监控器

import time

def timer(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 complex_calculation():
    # 模拟复杂计算
    time.sleep(1.5)

complex_calculation()

2. 权限守卫者

def login_required(func):
    def wrapper(user, *args, **kwargs):
        if not user.is_authenticated:
            raise PermissionError("需要登录后才能访问")
        return func(user, *args, **kwargs)
    return wrapper

@login_required
def view_profile(user):
    print(f"欢迎查看个人资料:{user.username}")

3. 缓存加速器

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(30))  # 速度提升立竿见影

4. 日志记录仪

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"[日志] 开始执行:{func.__name__}")
        result = func(*args, **kwargs)
        print(f"[日志] 执行完成:{func.__name__}")
        return result
    return wrapper

三、装饰器的进阶技巧

1. 带参数的装饰器

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

@repeat(3)
def alarm():
    print("请注意!")

alarm()  # 输出3次警告

2. 类装饰器

class CountCalls:
    def __init__(self, func):
        self.func = func
        self.calls = 0

    def __call__(self, *args, **kwargs):
        self.calls += 1
        print(f"第{self.calls}次调用")
        return self.func(*args, **kwargs)

@CountCalls
def api_request():
    # 模拟API调用
    pass

api_request()
api_request()

四、装饰器的最佳实践

  1. 保持装饰器通用性:使用*args**kwargs接收任意参数
  2. 保留函数元信息:使用@functools.wraps(func)装饰wrapper
  3. 避免装饰器嵌套过深:超过3层的装饰器要考虑重构
  4. 合理处理异常:在wrapper中添加异常处理逻辑
  5. 注意执行顺序:装饰器的应用顺序是自下而上的
from functools import wraps

def proper_decorator(func):
    @wraps(func)  # 保持原函数信息
    def wrapper(*args, **kwargs):
        try:
            print("装饰器前置操作")
            return func(*args, **kwargs)
        except Exception as e:
            print(f"捕获异常:{str(e)}")
        finally:
            print("装饰器后置操作")
    return wrapper

五、装饰器的妙用场景

  • Flask路由注册:@app.route('/')
  • Django权限控制:@login_required
  • 单元测试标记:@pytest.mark.skip
  • 类型检查:@typechecked
  • 异步函数转换:@asyncio.coroutine
# Flask路由示例
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return "欢迎来到Python装饰器世界!"

结语:装饰器的哲学

装饰器不仅是一种语法糖,更体现了Python"显式优于隐式"的设计哲学。它像一位代码化妆师,在不改变本质的前提下为函数增添魅力;又像一位代码建筑师,搭建起功能扩展的桥梁。掌握装饰器,你就掌握了Python进阶之路上的一把金钥匙。

下次当你看到@符号时,不妨会心一笑:这简单的符号背后,藏着Python开发者追求代码优雅的永恒追求。现在,就让我们用装饰器,为代码穿上优雅的外衣,让程序世界变得更加美好吧!

如果本文对你有帮助,欢迎点赞收藏!关于Python装饰器的更多深度技巧,我们下期再见~

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容