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

Python装饰器函数:添加额外的功能或修饰函数

发布时间:2023-06-13 00:46:15

Python装饰器函数

Python装饰器函数是一种很有用的编程技巧,它可以用来添加额外的功能或修饰函数。在Python中,函数是一种对象,因此可以将函数作为参数传递给其他函数,也可以将其作为返回值返回。

装饰器函数就是用来修饰其他函数的函数,它接受一个函数作为参数,并返回一个修饰后的函数。用装饰器函数修改其他函数,可以让我们在不改变原始函数的情况下添加功能,这样可以使得代码更加简洁和易于维护。

下面我们来看一个简单的装饰器函数。

def my_decorator(func):

    def wrapper():

        print("Before the function is called.")

        func()

        print("After the function is called.")

    return wrapper

@my_decorator

def say_hello():

    print("Hello world!")

我们定义了一个名为my_decorator的函数,它接受一个func参数,这个参数是一个函数对象。my_decorator返回一个wrapper函数,它在调用原始函数之前和之后打印一些信息。

我们然后用@my_decorator装饰了一个名为say_hello的函数,现在每次调用say_hello函数,实际上会调用wrapper函数。因此,在调用原始函数之前和之后,会输出一些信息。

下面我们来看一下如何编写一个可以带参数的函数装饰器。

def my_decorator(func):

    def wrapper(*args, **kwargs):

        print("Before the function is called.")

        result = func(*args, **kwargs)

        print("After the function is called.")

        return result

    return wrapper

在这个例子中,wrapper函数可以处理任意数量和类型的参数。我们使用*args和**kwargs来表示任意数量和任意类型的参数。这就允许我们使用装饰器来修饰任意类型的函数。

现在我们来看一下装饰器函数可以实现的一些常见的额外功能。

1. 记录日志

一个通用的应用场景是记录函数调用的日志。你可以在函数调用的前后记录函数名、参数和返回值。

def log_func_calls(func):

    def wrapper(*args, **kwargs):

        print(f"Call {func.__name__} with {args}")

        result = func(*args, **kwargs)

        print(f"Return {result}")

        return result

    return wrapper

在这个装饰器中,我们获取函数名和参数,记录在日志中,然后调用原函数,并将返回值记录在日志中。如果调用的函数返回的不是None,那么返回结果。

2. 记录时间

你也可以用装饰器来记录函数运行的时间。

import time

def time_it(func):

    def wrapper(*args, **kwargs):

        start = time.time()

        result = func(*args, **kwargs)

        end = time.time()

        print(f"Call {func.__name__}: {end - start:.5f} seconds")

        return result

    return wrapper

这个装饰器实现了一个计时器,它记录了调用函数所花费的时间,并打印出来。time.time()函数返回当前时间,使用start来记录调用函数之前的时间,使用end来记录调用函数之后的时间。我们还要使用Python中的格式化字符串来将运行时间输出为保留5位小数的字符串。

3. 缓存函数

有时候,我们希望避免重复计算某个函数。这时候,可以使用装饰器来实现一个缓存的版本,避免重复计算。

def memo(func):

    cache = {}

    def wrapper(*args):

        if args in cache:

            return cache[args]

        result = func(*args)

        cache[args] = result

        return result

    return wrapper

这个装饰器实现了一个简单的缓存。如果我们已经计算过一个函数,那么我们就可以在缓存中找到结果,而不是再次计算。注意,我们使用args作为缓存的键,这意味着单个参数的函数才能使用这个缓存。

在 Python 中使用装饰器可以给我们带来很多好处。它让我们可以在不修改原函数的前提下,实现某些额外的功能。因此,装饰器可以让我们的代码更加清晰、简洁和易于维护。