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

Python中的装饰器:用来扩展函数的功能,例如计时、日志记录等等

发布时间:2023-06-25 06:17:38

装饰器是Python中一种非常强大的语法结构,它可以用来扩展函数的功能,例如计时、日志记录等等。装饰器是一种函数,它接受另一个函数作为参数,并返回一个新函数,新函数通常会对原有的函数进行加强或改进。使用装饰器的好处是可以将代码逻辑分离,将复杂的功能封装在装饰器中,让函数变得简单清晰。

在Python中,装饰器使用@符号进行定义,例如下面的代码:

def log(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@log
def myfunc():
    print("Hello, World!")

myfunc()

这个例子中,@log表示在对myfunc()函数进行装饰。装饰的过程是,将myfunc()函数传递给log()函数作为参数,并返回一个新的函数wrapper()。在wrapper()函数中,首先输出了函数的调用名称,然后调用了原有的函数myfunc()。因此,执行myfunc()时,不仅会输出“Hello, World!”,还会输出“Calling function myfunc”。

这个例子只是装饰器的一个简单示例。在实际应用中,装饰器的功能可以非常丰富。下面介绍几种常用的装饰器:

1. 计时装饰器

计时装饰器用于记录函数的执行时间,如下所示:

import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"Function {func.__name__} took {end-start:.2f}s to execute.")
        return result
    return wrapper

@timeit
def myfunc():
    time.sleep(1)
    print("Hello, World!")

myfunc()

这个装饰器使用了time模块,记录了函数的开始时间和结束时间,并计算了函数的执行时间。当调用myfunc()函数时,会输出“Function myfunc took 1.00s to execute。”。

2. 缓存装饰器

缓存装饰器用于优化某些复杂函数的性能,例如递归斐波那契数列函数。这个函数的计算开销非常大,因此可以将已计算过的中间结果缓存下来,避免重复计算,提高程序效率。如下所示:

def memoize(func):
    cache = {}
    def wrapper(*args):
        if args in cache:
            return cache[args]
        else:
            result = func(*args)
            cache[args] = result
            return result
    return wrapper

@memoize
def fibonacci(n):
    if n in (0, 1):
        return n
    else:
        return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(10))

这个装饰器通过使用一个字典dict来缓存已求得的中间结果,如果下次需要求相同的结果,则直接从缓存中取出,避免了重复计算。对于fibonacci(10)函数调用,需要计算fibonacci(9)和fibonacci(8)两个结果,而这两个结果在缓存中已经存在,因此可以避免重复计算。

3. 日志装饰器

日志装饰器用于记录函数的执行过程及结果,便于程序调试和性能分析。如下所示:

def logger(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} was called with args {args} and kwargs {kwargs} and returned {result}")
        return result
    return wrapper

@logger
def myfunc(x, y, z=0):
    return x * y + z

myfunc(4, 5, z=6)

这个装饰器在函数执行前和执行后输出相关信息,方便调试和性能分析。执行myfunc(4, 5, z=6)时,输出“Function myfunc was called with args (4, 5) and kwargs {'z': 6} and returned 26”。

总之,装饰器是一种非常实用的Python语法结构,它可以用来扩展函数的功能,方便代码编写和调试。相信在日常Python开发中,装饰器会成为开发者的得力助手。