Python语言10个经典的自动化装饰器

2067 篇文章 51 订阅
797 篇文章 1 订阅

在 Python 中,装饰器是一种强大的工具,使用装饰器可以使自动化过程更加灵活和可扩展。装饰器可以在不改变原有代码的情况下,为函数或类添加新的功能或行为。这样可以保持原有代码的简洁性和可读性,同时实现功能的增强。另外,装饰器也可以帮助实现代码的复用,减少重复代码的编写,提高代码的可维护性和可重用性。最重要的是,装饰器可以使自动化过程更加模块化和解耦,方便对不同功能进行单独的调整和管理。因此,使用装饰器可以提高自动化过程的效率和可靠性。下面列出了一些经典的装饰器示例,这些装饰器涵盖了从简单的日志记录到更复杂的事务处理。

1. 日志记录

记录函数的调用时间和参数。

import functools
import time

def log(func):
    @functools.wraps(func)
def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} called with args: {args}, kwargs: {kwargs}. Execution time: {end_time - start_time:.4f} seconds")
return result
return wrapper

@log
def my_function(a, b):
    time.sleep(1)
return a + b

print(my_function(1, 2))

2. 错误处理

捕获并处理函数执行过程中可能出现的异常。

def error_handler(func):
    @functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
            print(f"Error occurred in {func.__name__}: {e}")
return wrapper

@error_handler
def risky_operation():
raise ValueError("Something went wrong")

risky_operation()

3. 缓存

缓存函数的结果,避免重复计算。

from functools import lru_cache

@lru_cache(maxsize=None)
def expensive_computation(n):
    print("Computing...")
return n * n

print(expensive_computation(5))
print(expensive_computation(5))  # 不再打印 "Computing..."

4. 参数验证

确保传入的参数符合预期。

def validate_params(func):
    @functools.wraps(func)
def wrapper(a, b):
if not isinstance(a, int) or not isinstance(b, int):
raise TypeError("Arguments must be integers")
return func(a, b)
return wrapper

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

print(add(1, 2))
# print(add(1, "two"))  # 会抛出 TypeError

5. 重试机制

当函数执行失败时自动重试一定次数。

import time

def retry(times=3, delay=1):
def decorator_retry(func):
        @functools.wraps(func)
def wrapper(*args, **kwargs):
for _ in range(times):
try:
return func(*args, **kwargs)
except Exception as e:
                    print(f"Retrying {func.__name__} after {delay} seconds due to {e}")
                    time.sleep(delay)
return None
return wrapper
return decorator_retry

@retry(times=3, delay=2)
def network_request():
    print("Making request...")
raise ConnectionError("Network is unreachable")

network_request()

6. 事务处理

确保一组操作要么全部成功,要么全部失败。

def transactional(func):
    @functools.wraps(func)
def wrapper(*args, **kwargs):
try:
            result = func(*args, **kwargs)
            commit()  # 假设 commit() 是提交事务的方法
return result
except Exception as e:
            rollback()  # 假设 rollback() 是回滚事务的方法
raise e
return wrapper

@transactional
def process_order(order_id):
# 处理订单逻辑
pass

7. 计时器

测量函数执行的时间。

def timer(func):
    @functools.wraps(func)
def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time:.4f} seconds")
return result
return wrapper

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

slow_function()

8. 调用计数

统计函数被调用的次数。

def call_counter(func):
    @functools.wraps(func)
def wrapper(*args, **kwargs):
        wrapper.calls += 1
        print(f"Function {func.__name__} was called {wrapper.calls} times.")
return func(*args, **kwargs)
    wrapper.calls = 0
return wrapper

@call_counter
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")
say_hello("Bob")

9. 限制调用频率

限制函数在一定时间内被调用的最大次数。

import threading

def rate_limited(max_per_second):
    min_interval = 1.0 / float(max_per_second)

def decorate(func):
        lock = threading.Lock()
        last_time_called = [0.0]

        @functools.wraps(func)
def rate_limited_function(*args, **kwargs):
            lock.acquire()
            elapsed = time.time() - last_time_called[0]
            left_to_wait = min_interval - elapsed
if left_to_wait > 0:
                time.sleep(left_to_wait)
            ret = func(*args, **kwargs)
            last_time_called[0] = time.time()
            lock.release()
return ret

return rate_limited_function

return decorate

@rate_limited(5)
def send_message(message):
    print(f"Sending message: {message}")

send_message("Hello")
send_message("World")

10. 限制内存使用

限制函数运行时使用的内存大小。

import resource
import functools

def limit_memory(max_memory):
def decorator_limit_memory(func):
        @functools.wraps(func)
def wrapper(*args, **kwargs):
            soft, hard = resource.getrlimit(resource.RLIMIT_AS)
            resource.setrlimit(resource.RLIMIT_AS, (max_memory, hard))
try:
                result = func(*args, **kwargs)
finally:
                resource.setrlimit(resource.RLIMIT_AS, (soft, hard))
return result
return wrapper
return decorator_limit_memory

@limit_memory(1024*1024*100)  # 限制为 100 MB
def memory_intensive_task():
# 假设这里有大量内存消耗的操作
pass

memory_intensive_task()

这些装饰器展示了 Python 装饰器的一些常见用途。它们可以帮助你在不修改原始函数代码的情况下增加额外的功能或行为。在实际开发中,你可以根据需求自由组合这些装饰器,或者创建自己的定制装饰器。

最后: 下方这份完整的软件测试视频教程已经整理上传完成,需要的朋友们可以自行领取【保证100%免费】

在这里插入图片描述

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值