python 装饰器

装饰器(Decorator)是Python语言中的一种高级技巧,可以在不改变原有代码的基础上,动态地给函数或类增加额外的功能。本质上,装饰器就是一个普通函数,它可以接受一个或多个参数,并且返回一个函数作为结果。

装饰器的语法如下:

@decorator_function
def function_to_be_decorated():
    # Function body

其中 decorator_function 表示装饰器函数,function_to_be_decorated 表示要被装饰的函数。

注意事项:

  1. 装饰器必须是一个可调用的对象(callable),即函数、类或实现了 __call__ 魔法方法的类的实例。
  2. 装饰器可以有多层嵌套,在应用多个装饰器时,从内到外依次执行。
  3. 装饰器可以接受参数,例如 @decorator(arg1, arg2)
  4. 被装饰的函数的元信息(比如文档字符串、名称、注释和参数签名)会丢失,需要使用 functools.wraps() 函数来解决这个问题。

下面是一个简单的装饰器示例,用于计算函数运行时间:

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"Function {func.__name__} took {end_time - start_time:.2f} seconds to run.")
        return result
    return wrapper

@timing_decorator
def my_function():
    # Function body

my_function()

该装饰器函数接受一个函数作为参数,返回一个包装器函数,用于统计被装饰函数的运行时间。注意,在 wrapper() 函数中,使用了可变长参数 *args 和关键字参数 **kwargs 来接收任意数量和类型的参数,并将它们传递给原始函数。

输出结果类似于:

Function my_function took 0.00 seconds to run.

再举一个装饰器的例子,用于验证用户是否具有访问权限:

def authenticated(func):
    def wrapper(*args, **kwargs):
        # 模拟身份验证
        is_authenticated = True  # 假设用户已登录
        if is_authenticated:
            return func(*args, **kwargs)
        else:
            return "Access denied. Please log in first."
    return wrapper

@authenticated
def my_function():
    # Function body

result = my_function()
print(result)

该装饰器函数接受一个函数作为参数,返回一个包装器函数,用于检查用户是否已经登录。如果用户已登录,则调用原始函数并返回结果;否则返回一个错误信息。

输出结果类似于:

Function result.

再举一个装饰器的例子,用于打印函数调用日志:

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__} with arguments: args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        return result
    return wrapper

@logger
def my_function(x, y):
    # Function body

result = my_function(1, 2)
print(result)

该装饰器函数接受一个函数作为参数,返回一个包装器函数,用于在函数被调用时输出日志信息。在 wrapper() 函数中,先打印出函数名称和参数列表,再调用原始函数,并返回结果。

接下来使用装饰器语法 @logger 来修饰一个名为 my_function 的函数,该函数接受两个参数 xy。在代码末尾调用 my_function(1, 2),以触发装饰器的执行,并输出结果。

输出结果类似于:

Calling function my_function with arguments: args=(1, 2), kwargs={}
result.

总之,装饰器是Python语言中非常灵活和强大的特性,可以帮助我们实现各种功能,例如计时、身份验证、日志记录等。但是,在使用装饰器时需要注意一些细节和陷阱,例如装饰器顺序、装饰器内部变量作用域等。因此,我们需要谨慎地使用装饰器,并根据实际情况选择最佳的方案。

posted @ 2023-05-04 13:46  乐瓜乐虫  阅读(40)  评论(0)    收藏  举报