c语言编程笔录

首页 >   > 笔记大全

笔记大全

理解Python中的装饰器

更新时间:2023-12-07

什么是装饰器?

装饰器是Python中一种特殊的语法,它允许开发人员修改或扩展函数或类的行为。简单来说,装饰器是一个可以接受一个函数并返回一个函数的函数。装饰器可以用于面向对象编程的类的方法和属性,也可以用于模块级别的函数和方法,还可以用于Decorated Function的修饰或装饰。

例如,以下是使用Python装饰器的代码:


def my_decorator(f):
    def wrapper():
        print("Before function execution")
        f()
        print("After function execution")
    return wrapper

@my_decorator
def say_hello():
    print("Hello World")

say_hello()

在上面的代码中,定义了一个my_decorator函数,它接受一个函数作为参数并返回一个封装的函数wrapper,wrapper函数在函数执行前后打印一些内容。这个 @my_decorator 语法是 Python 的语法糖, 它等同于下面这个简单的赋值语句:


say_hello = my_decorator(say_hello)

如何使用装饰器?

使用装饰器很简单,只需要在装饰器函数之上添加 @ 符号,后面跟着装饰器的名称。当我们调用被修饰的函数时,实际上是在调用装饰器,而装饰器返回的函数会被执行。

例如,以下代码展示了如何给一个函数添加装饰器:


def my_decorator(f):
    def wrapper():
        print("Before function execution")
        f()
        print("After function execution")
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("John")

运行此代码将会报错,因为 decorated 函数通过 @my_decorator 装饰器中的嵌套函数 wrapper 来调用. 所以,这个装饰器函数需要返回一个接受任意个参数的函数. 所以,我们再修改一下 my_decorator 函数:


def my_decorator(f):
    def wrapper(*args, **kwargs):
        print("Before function execution")
        f(*args, **kwargs)
        print("After function execution")
    return wrapper

@my_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("John")

在上面的代码中,首先定义了一个名为 my_decorator 的装饰器函数,它接收一个函数作为参数,返回一个新的封装后的函数 wrapper。然后,使用 @ 符号将装饰器应用到函数 say_hello 上。最后,调用 say_hello 函数,被装饰器包装后的函数会被执行。

装饰器的应用场景

装饰器通常用于以下场景: - 认证和授权:使用装饰器来限制对某一资源的访问,例如访问某些API时需要添加Token或者Session等身份验证信息。 - 记录日志:使用装饰器来记录函数的执行过程,例如记录函数的名称、参数和返回值。 - 缓存:使用装饰器来缓存函数的输出结果,以减少重复执行相同操作的时间。 - 测量函数执行时间:使用装饰器来测量函数的执行时间,以便优化代码或提高性能。 例如,以下是一个用于记录函数执行时间的装饰器的例子:

import time

def timeit(f):
    def wrapper(*args, **kwargs):
        start = time.time()
        ret = f(*args, **kwargs)
        end = time.time()
        print(f"Time taken: {end-start:.6f}")
        return ret
    return wrapper

@timeit
def calculate_sum(n):
    return sum(range(n))

calculate_sum(100000)
运行此代码将会输出类似于 “Time taken: 0.000094” 的值,表示计算 1 到 100000 的和所花费的时间。这个装饰器函数使用了 time 模块来测量函数的执行时间,并打印出时间差。