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

如何在Python中使用装饰器

发布时间:2023-05-21 18:57:20

装饰器是 Python 中的一个重要概念,它是一种能够在不改变函数原有定义的情况下,增强函数功能的技术。装饰器可以用于函数、类、方法等任何对象的修饰,可以将原始对象包装成新的对象,从而为原对象添加额外的功能。本文将从实例出发,讲解如何在 Python 中使用装饰器。

一、基础概念

在开始前,我们需要了解一些基础概念。

首先是闭包。闭包是指在函数内部定义了一个函数,并返回了该函数的引用。返回的函数可以访问到在外部函数中定义的变量。这个特定的函数就是闭包。它可以当作一个函数工厂,每次生成的函数都是不同的。

接着是函数作为参数传递。Python 中函数是一种对象,因此可以将一个函数作为另一个函数的参数传递。

还有函数作为返回值。Python 中也可以将一个函数作为返回值。

以上三个概念将会是装饰器的重要组成部分。

二、装饰器的定义

装饰器本质上是一个函数,在作用于其他函数时,它能够修改其他函数的行为。装饰器主要用于增强已有函数的功能,而不需要对函数进行修改。装饰器的定义格式如下:

def decorator(func):
    def wrapper(*args, **kwargs):
        # 在执行原函数前的操作
        res = func(*args, **kwargs)
        # 在执行原函数后的操作
        return res
    return wrapper

其中,decorator 就是一个装饰器。func 是被修饰的函数,wrapper 则是新生成的函数。在 wrapper 函数中我们可以在调用原函数 func 之前、之后增加相应的操作。

三、装饰器的使用

三个小例子将演示装饰器的使用。

例一:计时器

计时器装饰器可以用于计算一个函数的执行时间。

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        res = func(*args, **kwargs)
        end_time = time.time()
        print(f'{func.__name__} took {(end_time-start_time)*1000:.2f} ms')
        return res
    return wrapper

@timer
def foo():
    time.sleep(2)

if __name__ == '__main__':
    foo()

在上面的例子中,我们定义了 timer 装饰器,然后用装饰器修饰了函数 foo。当我们运行这个程序时,会输出类似下面的信息:

foo took 2000.24ms

通过这个追踪器我们可以查看每个函数所需要的时间。这对于优化代码非常有帮助。

例二:调试器

在Python中,调试器也可以被实现为装饰器。下面的例子展示了可用于调用堆栈的装饰器。

def debug(func):
    def wrapper(*args, **kwargs):
        print(f'Executing {func.__name__}() with args: {args}, kwargs: {kwargs}')
        return func(*args, **kwargs)
    return wrapper

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

if __name__ == '__main__':
    result = add(2, 3)
    print(result)

在上面的例子中,我们定义了 debug 装饰器,然后将其应用在函数 add 上。运行程序后,会输出类似下面的信息:

Executing add() with args: (2, 3), kwargs: {}
5

例三:授权登录

有时候应用程序中需要授权才能执行某些操作。下面是一个授权登录例子:

user = {'name': 'admin', 'password': 'password'}

def auth(func):
    def wrapper(*args, **kwargs):
        name = input("Enter your name:")
        password = input("Enter your password:")
        if name == user['name'] and password == user['password']:
            return func(*args, **kwargs)
        else:
            print("Invalid login credentials")
            return None
    return wrapper

@auth
def do_something():
    print("You are authorized")

if __name__ == '__main__':
  do_something()

在上面的例子中,我们定义了 auth 装饰器,然后将其应用在函数 do_something 上。函数 do_something 需要使用授权才能执行。当我们运行程序时,会提示输入用户名和密码。如果输入的用户名和密码与预定的一致,则可以执行函数 do_something

四、总结

装饰器是 Python 中的一个非常重要的概念,它可以让我们在不修改原始代码的情况下,增强函数的功能。此外,装饰器还可以重构代码、调试代码以及实现授权登录等功能。本文介绍了装饰器的定义和使用,并给出了三个小例子。通过这些例子,我们可以更好地理解和使用装饰器。