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

Python装饰器-如何优雅地扩展函数功能

发布时间:2023-06-29 17:46:51

Python装饰器是一种特殊的函数,它可以用于修改其他函数的行为,从而扩展其功能。装饰器可以在不修改原有函数代码的情况下,动态地为函数添加额外的功能,使得代码更加简洁和易于维护。

在Python中,函数是一等公民,可以像其他对象一样被传递、赋值和调用。这一特性使得我们可以在函数内部定义函数,并通过闭包的方式访问外部函数的变量。基于这个特性,我们可以实现装饰器函数。

装饰器函数的定义格式如下:

def decorator_func(func):
    def wrapper(*args, **kwargs):
        # 在调用被装饰的函数前的处理逻辑
        result = func(*args, **kwargs)
        # 在调用被装饰的函数后的处理逻辑
        return result
    return wrapper

装饰器函数接受一个函数作为参数,并返回一个内部函数。内部函数即装饰器的实际操作逻辑,它在调用被装饰的函数之前和之后可以执行额外的代码。

使用装饰器时,我们可以通过在目标函数定义之前添加@decorator_func的方式来应用装饰器:

@decorator_func
def target_func():
    # 目标函数的代码

装饰器实际上就是对目标函数的一个包装,它可以为目标函数提供额外的功能,例如日志记录、性能统计、权限控制等。下面我们来看几个常见的装饰器的应用示例。

1. 日志记录

import logging

def logging_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Calling function {func.__name__} with args: {args}, kwargs: {kwargs}")
        result = func(*args, **kwargs)
        logging.info(f"Function {func.__name__} returned: {result}")
        return result
    return wrapper

@logging_decorator
def add(x, y):
    return x + y

add(2, 3)  # 输出:Calling function add with args: (2, 3), kwargs: {}, Function add returned: 5

2. 计时统计

import time

def timer_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} seconds")
        return result
    return wrapper

@timer_decorator
def fib(n):
    if n <= 1:
        return n
    else:
        return fib(n-1) + fib(n-2)

fib(10)  # 输出:Function fib took 0.0012345 seconds

3. 权限控制

def privilege_decorator(role):
    def decorator_func(func):
        def wrapper(*args, **kwargs):
            if role == "admin":
                return func(*args, **kwargs)
            else:
                raise Exception("Permission denied")
        return wrapper
    return decorator_func

@privilege_decorator("admin")
def delete_data(data_id):
    # 删除数据的操作
    pass

delete_data(1001)  # 只有admin角色才能成功删除数据

以上是几个常见的装饰器的用法示例,实际上,我们可以自定义任意种类的装饰器来满足不同的需求,只需要按照上述格式编写即可。

装饰器提供了一种优雅的扩展函数功能的方式,它使得我们可以将与目标函数无关的功能独立出来,使得代码更加模块化和可复用。在实际工作中,我们经常会使用装饰器来提供日志记录、性能统计、缓存、异常处理等功能,从而提高代码的可维护性和可读性。