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

Python装饰器函数的用法及实例

发布时间:2023-05-19 13:54:52

Python中的装饰器是一种非常有用的技巧,它可以在不改变原函数代码的情况下,为函数添加额外的功能。Python中装饰器函数的实现方法非常简单,只需要在装饰器函数中定义一个包裹函数,然后将原函数作为参数传递给包裹函数即可。在这篇文章中,我将详细介绍Python装饰器函数的用法及实例。

一、装饰器函数的用途

Python装饰器函数的主要用途是将某一函数与其它函数或类进行关联,从而达到某种预期的效果,这种效果可以是在函数运行前后添加额外的处理逻辑,保存函数的执行结果,判断函数是否已经被执行等等。同时,装饰器函数也可以让函数更加易于扩展和修改,提高代码重用性和可维护性。

二、装饰器函数的基本语法

定义装饰器函数的基本语法如下:

def decorator_function(original_function):
    def wrapper_function(*args, **kwargs):
        # 在函数执行之前添加额外的处理逻辑
        result = original_function(*args, **kwargs)
        # 在函数执行之后添加额外的处理逻辑
        return result
    return wrapper_function

在这段代码中,我们定义了一个装饰器函数decorator_function,它接收一个函数作为参数original_function,并且返回一个包裹函数wrapper_function。在包裹函数中,我们可以添加一些额外的处理逻辑,如在函数执行前和执行后分别打印一些日志信息。同时,我们还在包裹函数中调用原函数original_function并返回其结果result

三、装饰器函数的实例

下面我们将介绍一些实际使用中常见的装饰器函数示例。

1. 函数计时器

我们经常需要知道某个函数执行的时间,如果对于所有函数都手动记录时间将会是一个繁琐的过程。这个时候,我们可以编写一个装饰器函数来自动记录函数执行时间。代码如下:

import time

def timer(original_function):
    def wrapper_function(*args, **kwargs):
        start_time = time.time()
        result = original_function(*args, **kwargs)
        end_time = time.time()
        print(f'执行函数 {original_function.__name__} 花费了 {end_time-start_time:.2f} 秒')
        return result
    return wrapper_function

@timer
def foo():
    time.sleep(2)
    print('Done')

foo()

在这个例子中,我们定义了一个装饰器函数timer,它记录了函数的起始时间和结束时间,并通过在包裹函数中调用原函数来计算函数执行时间。我们使用@timer来装饰原函数foo,这样在调用foo函数时,它会自动被装饰器函数timer所包装。

2. 身份验证

有些时候,我们希望某个函数只能在用户身份验证通过后才能被调用。这个时候,我们可以编写一个装饰器函数来验证用户是否已经登录。代码如下:

def login_required(original_function):
    def wrapper_function(*args, **kwargs):
        if not is_logged_in():
            return '请先登录'
        else:
            return original_function(*args, **kwargs)
    return wrapper_function

@login_required
def add(a, b):
    return a + b

# 如果未登录,则调用函数时会返回 '请先登录'

在这个例子中,我们定义了一个装饰器函数login_required,它验证了用户是否已经登录。在包裹函数中,我们使用函数is_logged_in()来判断用户是否已经登录。如果用户未登录,则返回提示信息;否则调用原函数。

3. 缓存函数结果

有些时候,我们希望缓存函数的执行结果,以便以后重复调用函数时可以直接返回结果,而无需重新执行函数。这个时候,我们可以编写一个装饰器函数来缓存函数的结果。代码如下:

def memoize(original_function):
    cache = {}

    def wrapper_function(*args):
        if args in cache:
            return cache[args]
        else:
            result = original_function(*args)
            cache[args] = result
            return result
    
    return wrapper_function

@memoize
def fibonacci(n):
    if n < 2:
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

#       次计算会较慢,但后续调用将会非常快

在这个例子中,我们定义了一个装饰器函数memoize,它使用了一个字典cache来缓存函数结果。在包裹函数中,我们根据传入的参数来判断结果是否已经缓存,如果已经缓存,则返回缓存结果;否则调用原函数,并将结果缓存起来。

四、总结

Python装饰器函数是一种非常有用的技巧,它可以为函数添加额外的功能,同时也提高了代码的可维护性和重用性。本文介绍了装饰器函数的基本语法和常见用途,希望读者可以通过阅读本文,更好地理解和应用装饰器函数。