Python 向装饰器添加参数

  • Post category:Python

Python 装饰器本身就是一个非常强大的工具,它可以非常灵活地扩展函数的功能。然而,有时我们需要在装饰器中添加一些参数,以便更加灵活地调用装饰器。下面是 Python 中向装饰器添加参数的完整攻略。

装饰器基础知识

在 Python 中,一个装饰器实际上就是一个函数,它可以用来扩展一个函数的功能。一个装饰器通常会接受一个函数作为参数,并返回一个新的函数,这个新函数就是原函数的增强版本。

下面是一个简单的装饰器示例,它可以在调用函数前后打印出一些信息:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print("调用函数:%s" % func.__name__)
        result = func(*args, **kwargs)
        print("函数返回值:%s" % result)
        return result
    return wrapper

@log_decorator
def my_func(x, y):
    return x + y

my_func(1, 2)

输出结果为:

调用函数:my_func
函数返回值:3

向装饰器添加参数

如果我们需要修改装饰器的行为,可以向装饰器中添加一些参数。我们可以在定义装饰器时,通过函数参数的方式传递参数,然后在内部函数中使用这些参数来修改装饰器的行为。

以下是一个接受参数的装饰器示例,它可以打印出函数执行时间:

import time

def time_cost_decorator(print_result=True):
    def _decorator(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            cost_time = end_time - start_time
            if print_result:
                print("函数 %s 执行时间:%s 秒" % (func.__name__, cost_time))
            return result
        return wrapper
    return _decorator

@time_cost_decorator(print_result=True)
def my_func(x, y):
    time.sleep(1)
    return x + y

my_func(1, 2)

在上面这个示例中,我们向装饰器 time_cost_decorator 添加了一个参数 print_result,它代表是否打印输出。在装饰器内部,我们使用这个参数来决定是否输出函数执行时间。

示例2:带参数的装饰器

有些时候,我们需要在装饰器内部传递参数,然后根据这些参数来修改装饰器的行为。我们可以通过定义一个额外的函数,它接受装饰器参数,返回一个带装饰器参数的装饰器。

以下是一个带参数的装饰器示例,它可以为装饰器指定一个前缀:

def prefix_decorator(prefix):
    def _decorator(func):
        def wrapper(*args, **kwargs):
            print("%s 开始执行" % prefix)
            result = func(*args, **kwargs)
            print("%s 执行结束" % prefix)
            return result
        return wrapper
    return _decorator

@prefix_decorator(prefix='[INFO]')
def my_func(x, y):
    print("x + y = ", x + y)

my_func(1, 2)

在上面这个示例中,我们定义了一个新的函数 prefix_decorator,它接受一个参数 prefix,然后返回一个装饰器。

在调用装饰器时,我们使用 @prefix_decorator(prefix='[INFO]') 的语法来指定装饰器的参数。

总结

向装饰器添加参数是一种非常常见的技巧,它可以让装饰器更加灵活。我们可以通过定义一个装饰器函数,并使用额外的函数来接受装饰器参数,然后在内部函数中使用这些参数来修改装饰器的行为。