page contents

Python懒人必备:推荐7个高效实用的装饰器!

对于编程新手来说,Python装饰器可能是一个稍显复杂的概念。简单来说,装饰器是一个函数,它可以接受另一个函数作为参数,并返回一个新的函数(通常是修改后的原始函数的版本)。这个特性使得装饰器在Python中成为一种非常强大且灵活的工具,可以用于在不修改原始函数代码的情况下,为其添加新的功能或修改其行为。常用于统计时间、插入日志、性能度量、权限校验、缓存、事务处理等场景。

attachments-2024-09-hq2PeuSL66d66676295e8.jpg对于编程新手来说,Python装饰器可能是一个稍显复杂的概念。简单来说,装饰器是一个函数,它可以接受另一个函数作为参数,并返回一个新的函数(通常是修改后的原始函数的版本)。这个特性使得装饰器在Python中成为一种非常强大且灵活的工具,可以用于在不修改原始函数代码的情况下,为其添加新的功能或修改其行为。常用于统计时间、插入日志、性能度量、权限校验、缓存、事务处理等场景。

想象一下,你有一个函数,它负责计算两个数的和。现在,你希望为这个函数添加一个计时功能,以便知道它执行需要多长时间。使用装饰器,你可以在不修改原始函数的情况下实现这一点。你只需编写一个装饰器函数,它接受原始函数作为参数,并返回一个新的函数,这个新函数在调用原始函数之前和之后分别记录时间,并计算执行时间。然后,你可以将这个装饰器应用到你的原始函数上,从而得到一个具有计时功能的新函数。

下述,列举几个常见装饰器的用法及示例,希望对大家有些许帮助。

1、计时装饰器

计时装饰器在Python中主要用于测量函数的执行时间,这在性能调优和代码优化时非常有用。例如,当你有一个复杂的算法或函数,你想知道它需要多长时间才能完成,或者你想比较两个不同实现的性能差异,你可以使用计时装饰器来测量它们的运行时间。

import time

def timer(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} 秒")

        return result

    return wrapper

@timer

def test_function():

    time.sleep(3)

    print("示例函数执行完毕")

test_function()

2、日志装饰器

日志装饰器的主要用途是在不修改原函数代码的情况下,为函数增加日志记录的功能。这样可以帮助开发者更好地了解程序的运行状态,跟踪错误以及分析性能问题。

import logging

def log_decorator(func):

    def wrapper(*args, **kwargs):

        logging.basicConfig(level=logging.INFO)

        logging.info(f"开始执行 {func.__name__} 函数")

        result = func(*args, **kwargs)

        logging.info(f"{func.__name__} 函数执行完毕")

        return result

    return wrapper

@log_decorator

def example_function():

    print("示例函数执行中...")

example_function()

3、缓存装饰器

缓存装饰器主要用于优化程序的性能,特别是在处理重复计算或I/O操作时。

import functools

def cache_decorator(func):

    cache = dict()

    @functools.wraps(func)

    def wrapper(*args, **kwargs):

        key = (args, tuple(kwargs.items()))

        if key not in cache:

            cache[key] = func(*args, **kwargs)

        return cache[key]

    return wrapper

@cache_decorator

def example_function(x, y):

    return x + y

print(example_function(1, 2))  # 输出 3,计算并缓存结果

print(example_function(1, 2))  # 输出 3,从缓存中获取结果

也可以使用functools.lru_cache来实现缓存装饰器的效果

import functools

@functools.lru_cache(maxsize=None)
def example_function(x, y):
    return x + y

print(example_function(1, 2))  # 输出 3,计算并缓存结果
print(example_function(1, 2))  # 输出 3,从缓存中获取结果

functools.lru_cache使用最近最少使用(LRU)策略来管理缓存的大小,这意味着它会保留最近使用的函数调用结果,而将长时间未使用的结果清除以释放内存空间。此外,lru_cache还提供了一些高级参数,如最大缓存大小、缓存过期时间等,使得开发者可以根据需求对缓存行为进行更细致的控制。
4、类型检查装饰器
类型检查装饰器在Python中主要用于确保函数调用时参数的数据类型与预期匹配,从而提高代码的健壮性和可维护性。
from functools import wraps

def type_check(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # 获取函数的参数注解
        annotations = func.__annotations__
        
        # 遍历参数和注解,检查类型是否正确
        for arg, annotation in zip(args, annotations.values()):
            if not isinstance(arg, annotation):
                raise TypeError(f"参数 {arg} 的类型应为 {annotation},但实际类型为 {type(arg)}")
        
        # 调用原始函数
        return func(*args, **kwargs)
    
    return wrapper

# 使用装饰器进行类型检查
@type_check
def add(a: int, b: int) -> int:
    return a + b

print(add(1, 2))  # 输出 3
print(add("1", "2"))  # 抛出 TypeError,因为参数类型不正确
5、单例装饰器
单例模式是一种设计模式,用于确保一个类只有一个实例,并提供一个全局访问点。在Python中,可以使用装饰器来实现单例模式。以下是一个简单的单例装饰器示例:
def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance

@singleton
class MyClass:
    def __init__(self, x):
        self.x = x

a = MyClass(1)
b = MyClass(2)
print(a is b)  # 输出 True,说明 a 和 b 是同一个实例
6、重试装饰器
重试装饰器主要用于实现自动重试逻辑,以提高系统的稳定性和可靠性。以下是一个简单的重试装饰器示例:
import time
from functools import wraps

def retry(retries=3, delay=1):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for i in range(retries):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    if i == retries - 1:
                        raise e
                    time.sleep(delay)
        return wrapper
    return decorator

@retry(retries=5, delay=2)
def my_function():
     # 这里是你的函数实现
    pass

在这个示例中,retry 装饰器接受两个参数:retries 表示最大重试次数,默认为3次;delay 表示每次重试之间的延迟时间,默认为1秒。当被装饰的函数抛出异常时,装饰器会自动重试指定次数,并在每次重试之间等待指定的延迟时间。如果达到最大重试次数仍然失败,则抛出最后一次捕获到的异常。
7、性能度量装饰器
cProfile是Python内置的性能分析工具,可以用于测量函数的执行时间和调用次数等信息。以下是使用cProfile来实现性能度量装饰器的示例:
import cProfile
from functools import wraps

def performance_metric(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        profiler = cProfile.Profile()
        profiler.enable()
        result = func(*args, **kwargs)
        profiler.disable()
        profiler.print_stats()
        return result
    return wrapper

@performance_metric
def my_function():
    # 这里是你的函数实现
    pass
在这个示例中,我们首先导入了cProfile模块,并定义了一个名为performance_metric的装饰器。在装饰器内部,我们创建了一个cProfile.Profile对象,并启用它来开始性能分析。然后,我们调用原始函数并获取结果。最后,我们禁用性能分析器并打印出性能分析结果。
使用这个装饰器非常简单,只需要在需要测量性能的函数上方添加 @performance_metric 即可。例如,在上面的示例中,我们在 my_function 函数上使用了该装饰器,因此每次调用 my_function 时都会自动输出其性能分析结果。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2024-09-03 09:29
  • 阅读 ( 53 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
小柒
小柒

1470 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章