自学内容网 自学内容网

Python 装饰器

Python 装饰器

Python 装饰器(decorator)是一种用于扩展或修改现有函数功能的函数。它可以在不改变被装饰函数的源代码的情况下,为函数添加额外的行为。

装饰器的本质是一个函数,它接受一个函数作为参数,并返回一个新的函数。这个新函数通常会在内部调用被装饰的函数,并在调用前后添加一些额外的逻辑。

以下是一个简单的装饰器示例:

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        execution_time = (end_time - start_time) * 1000
        print(f"time is {execution_time} ms")
        return result
    return wrapper

@timer
def my_function(a, b):
    print(f"result is {a + b}")
    time.sleep(1) 

my_function(3, 4)

在上述示例中,timer 就是一个装饰器函数。它定义了一个内部函数 wrapper,该函数接受任意数量的位置参数 *args 和关键字参数 **kwargs

在 wrapper 函数内部,首先记录开始时间,然后调用被装饰的函数 func(*args, **kwargs),并获取其返回结果。接着计算函数的执行时间,打印出来,最后返回函数的执行结果。

使用 @timer 来装饰 my_function 函数,就相当于执行了 my_function = timer(my_function),将 my_function 替换为经过装饰后的 wrapper 函数。这样,当调用 my_function(3, 4) 时,实际上是在调用 wrapper(3, 4),从而实现了对函数执行时间的计算和打印,同时仍然能够得到原函数的返回结果。

装饰器的主要优点包括:

  • 遵循开放封闭原则:可以在不修改原有函数代码的基础上进行功能扩展。
  • 提高代码的复用性:可以将相同的装饰逻辑应用于多个函数。
  • 使代码更简洁、清晰:将额外的功能从函数本身的业务逻辑中分离出来。

装饰器还可以带有参数、用于类的方法等,以下是一些扩展的示例:

1.带参数的装饰器:

def deco_factory(argument):
    def deco(func):
        def wrapper(*args, **kwargs):
            # 使用参数进行一些额外的操作
            print(f"Decorator argument: {argument}")
            result = func(*args, **kwargs)
            return result
        return wrapper
    return deco

@deco_factory("my_argument")
def my_function(a, b):
    print(f"result is {a + b}")

my_function(3, 4)

2.类装饰器:

类也可以用作装饰器,通过实现 __call__ 方法来模拟函数的行为。

class MyDecorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        print("Before function execution")
        result = self.func(*args, **kwargs)
        print("After function execution")
        return result

@MyDecorator
def my_function(a, b):
    print(f"result is {a + b}")

my_function(3, 4)

3.多个装饰器的使用:

一个函数可以被多个装饰器装饰,装饰器的应用顺序与声明顺序相反。

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1 before")
        result = func(*args, **kwargs)
        print("Decorator 1 after")
        return result
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2 before")
        result = func(*args, **kwargs)
        print("Decorator 2 after")
        return result
    return wrapper

@decorator1
@decorator2
def my_function(a, b):
    print(f"result is {a + b}")

my_function(3, 4)

在这个例子中,调用 my_function(3, 4) 时,输出的顺序是 “Decorator 1 before”、“Decorator 2 before”、“result is 7”、“Decorator 2 after”、“Decorator 1 after”。

4.用装饰器来添加函数的日志记录功能

import logging

# 定义装饰器函数
def add_logging(func):
    def wrapper(*args, **kwargs):
        logging.info(f"Entering function: {func.__name__}")  # 记录进入函数的信息
        result = func(*args, **kwargs)
        logging.info(f"Exiting function: {func.__name__}, result: {result}")  # 记录函数退出及结果
        return result
    return wrapper

# 配置日志记录
logging.basicConfig(level=logging.INFO)

# 示例函数
@add_logging
def add_numbers(a, b):
    return a + b

add_numbers(2, 3)

在上述代码中,我们定义了一个名为 add_logging 的装饰器函数。它内部的 wrapper 函数负责记录函数进入和退出的日志信息以及函数的返回结果。

Python 内置了一些装饰器,例如 staticmethod、classmethod 和 property。staticmethod 用于定义类静态方法,它没有 self 参数,可以在不创建类实例的情况下调用;classmethod 的第一个参数不是 self 而是 cls,表示当前类;property 用于定义属性,可以通过类实例直接访问。

装饰器是 Python 中非常强大和灵活的特性,能够帮助开发者更优雅地组织和扩展代码的功能。通过使用装饰器,可以使代码更具可读性、可维护性和可扩展性。要深入理解和掌握装饰器,需要在实际编程中不断实践和体会。


原文地址:https://blog.csdn.net/zsh501736479/article/details/140636847

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!