欢迎访问宙启技术站
智能推送

Python函数装饰器实践技巧

发布时间:2023-11-20 18:45:18

Python函数装饰器是一种强大的工具,可以用来修改、扩展已有函数的功能。通过装饰器,我们可以在不修改原函数的情况下,给他添加额外的功能或者修改其行为。在本文中,我将分享一些关于Python函数装饰器的实践技巧。

1. 使用装饰器修改函数的行为:装饰器可以用来修改函数的行为,例如添加日志、计时等功能。例如下面的装饰器可以用来打印函数的运行时间:

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 my_function():
    time.sleep(2)

my_function()

2. 接收参数的装饰器:装饰器也可以接收参数,这样可以根据传入的参数来灵活地改变装饰器的行为。例如,下面的装饰器可以接收一个参数,用来指定函数的最大重试次数:

def retry(max_retries):
    def decorator(func):
        def wrapper(*args, **kwargs):
            retries = 0
            while retries < max_retries:
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    retries += 1
                    print(f'重试第{retries}次:{e}')
            raise RuntimeError(f'重试{max_retries}次后仍未成功')
        return wrapper
    return decorator

@retry(3)
def my_function():
    if random.randint(0, 10) < 5:
        raise ValueError('出错了')
    else:
        print('执行成功')

my_function()

3. 带参数的装饰器:有时候我们需要在装饰器中使用外部定义的变量,可以使用带参数的装饰器来实现。例如,下面的装饰器可以用来检查函数的运行时间是否超过指定的阈值:

def time_limit(max_time):
    def decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            execution_time = end_time - start_time
            if execution_time > max_time:
                print(f'{func.__name__}运行时间超过阈值:{execution_time}秒')
            else:
                print(f'{func.__name__}运行时间:{execution_time}秒')
            return result
        return wrapper
    return decorator

@time_limit(1)
def my_function():
    time.sleep(2)

my_function()

4. 装饰器链:装饰器可以通过将多个装饰器链式调用来实现复杂的功能。装饰器链的顺序是从上到下执行的。例如,下面的代码通过装饰器链实现了一个同时打印函数运行时间和参数的装饰器:

def print_args(func):
    def wrapper(*args, **kwargs):
        print(f'函数参数:{args}, {kwargs}')
        return func(*args, **kwargs)
    return wrapper

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
@print_args
def my_function(a, b):
    return a + b

my_function(1, 2)

在以上的实践中,我展示了一些Python函数装饰器的技巧,包括修改函数的行为、接收参数、带参数以及装饰器链。希望这些技巧能够帮助你更好地理解和应用Python函数装饰器。