Python中的装饰器:优雅地增强函数功能

简介: Python中的装饰器:优雅地增强函数功能

Python中的装饰器:优雅地增强函数功能

装饰器是Python中一个强大且灵活的特性,它允许我们在不修改原始函数代码的情况下,为函数添加额外的功能。本文将深入探讨装饰器的工作原理、实现方法以及实际应用场景。

什么是装饰器?

装饰器本质上是一个高阶函数,它接受一个函数作为参数,并返回一个新的函数。使用装饰器可以在运行时修改或增强函数的行为,而不需要改变函数本身的代码。

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

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

say_hello()

输出:

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

装饰器的实际应用

1. 性能分析装饰器

import time
from functools import wraps

def timer(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.4f}秒")
        return result
    return wrapper

@timer
def slow_function():
    time.sleep(2)
    return "完成"

result = slow_function()
print(result)

2. 缓存装饰器

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(10))

# 第二次计算会直接从缓存中获取结果
print(fibonacci(10))

3. 权限验证装饰器

def requires_auth(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        if not current_user.is_authenticated:
            raise PermissionError("需要登录")
        return func(*args, **kwargs)
    return wrapper

@requires_auth
def sensitive_operation():
    return "敏感操作执行成功"

带参数的装饰器

有时候我们需要装饰器本身也能接受参数,这就需要再嵌套一层函数:

def repeat(num_times):
    def decorator_repeat(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                result = func(*args, **kwargs)
            return result
        return wrapper
    return decorator_repeat

@repeat(num_times=3)
def greet(name):
    print(f"Hello {name}")

greet("World")

类装饰器

除了函数装饰器,Python还支持类装饰器:

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

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

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

say_hello()
say_hello()

装饰器的最佳实践

  1. 使用functools.wraps:保持原始函数的元信息(如函数名、文档字符串等)
  2. 避免副作用:装饰器应该透明地增强函数,而不是改变其核心行为
  3. 考虑可读性:复杂的装饰器可能会降低代码的可读性

总结

装饰器是Python中一个非常强大的特性,它提供了一种清晰、可重用的方式来修改或增强函数的行为。通过合理使用装饰器,我们可以实现横切关注点的分离,使代码更加模块化和可维护。

掌握装饰器不仅能让你的代码更加Pythonic,还能为你打开函数式编程的大门。希望本文能帮助你更好地理解和应用Python装饰器!

进一步学习建议

  • 深入了解闭包和函数作用域
  • 探索Python标准库中的装饰器(如@staticmethod, @classmethod)
  • 尝试实现更复杂的装饰器模式

Happy coding! 🐍

相关文章
|
2月前
|
存储 JavaScript Java
(Python基础)新时代语言!一起学习Python吧!(四):dict字典和set类型;切片类型、列表生成式;map和reduce迭代器;filter过滤函数、sorted排序函数;lambda函数
dict字典 Python内置了字典:dict的支持,dict全称dictionary,在其他语言中也称为map,使用键-值(key-value)存储,具有极快的查找速度。 我们可以通过声明JS对象一样的方式声明dict
186 1
|
2月前
|
算法 Java Docker
(Python基础)新时代语言!一起学习Python吧!(三):IF条件判断和match匹配;Python中的循环:for...in、while循环;循环操作关键字;Python函数使用方法
IF 条件判断 使用if语句,对条件进行判断 true则执行代码块缩进语句 false则不执行代码块缩进语句,如果有else 或 elif 则进入相应的规则中执行
280 1
|
2月前
|
Java 数据处理 索引
(numpy)Python做数据处理必备框架!(二):ndarray切片的使用与运算;常见的ndarray函数:平方根、正余弦、自然对数、指数、幂等运算;统计函数:方差、均值、极差;比较函数...
ndarray切片 索引从0开始 索引/切片类型 描述/用法 基本索引 通过整数索引直接访问元素。 行/列切片 使用冒号:切片语法选择行或列的子集 连续切片 从起始索引到结束索引按步长切片 使用slice函数 通过slice(start,stop,strp)定义切片规则 布尔索引 通过布尔条件筛选满足条件的元素。支持逻辑运算符 &、|。
165 0
|
2月前
|
测试技术 Python
Python装饰器:为你的代码施展“魔法”
Python装饰器:为你的代码施展“魔法”
242 100
|
3月前
|
设计模式 缓存 监控
Python装饰器:优雅增强函数功能
Python装饰器:优雅增强函数功能
275 101
|
2月前
|
缓存 Python
Python装饰器:为你的代码施展“魔法
Python装饰器:为你的代码施展“魔法
153 88
|
3月前
|
存储 缓存 测试技术
Python装饰器:优雅地增强函数功能
Python装饰器:优雅地增强函数功能
194 98
|
3月前
|
缓存 测试技术 Python
解锁Python超能力:深入理解装饰器
解锁Python超能力:深入理解装饰器
134 2
|
算法 Python 容器
Python编程 - 不调用相关choose库函数,“众数“挑选器、随机挑选器 的源码编程实现
Python编程 - 不调用相关choose库函数,“众数“挑选器、随机挑选器 的源码编程实现
242 0
|
算法 Python
Python编程的函数—内置函数
Python编程的函数—内置函数
180 0

推荐镜像

更多