📜  带装饰器的计时函数Python

📅  最后修改于: 2022-05-13 01:54:32.478000             🧑  作者: Mango

带装饰器的计时函数Python

Python中的一切都是对象。 Python的函数也是对象。因此,像任何其他对象一样,它们可以被变量引用,存储在字典或列表等数据结构中,作为参数传递给另一个函数,并作为另一个函数的值返回。在本文中,我们将看到带有装饰器的计时函数。

装饰器:装饰器用于增强或修改函数。装饰器是一个高阶函数,它包装另一个函数并对其进行增强或更改。

例子 :

通过编写我们自己的装饰器来解释它是什么的最好方法。假设您想在某个函数的输出前后打印 * 10 次。在每个函数一次又一次地使用打印语句会非常不方便。我们可以在装饰器的帮助下有效地做到这一点。

代码:



Python3
def my_decorator(func):
    def wrapper_function(*args, **kwargs):
        print("*"*10)
        func(*args,  **kwargs)
        print("*"*10)
    return wrapper_function
  
  
def say_hello():
    print("Hello Geeks!")
  
@my_decorator
def say_bye():
    print("Bye Geeks!")
  
  
say_hello = my_decorator(say_hello)
say_hello()
say_bye()


Python3
from time import time
  
  
def timer_func(func):
    # This function shows the execution time of 
    # the function object passed
    def wrap_func(*args, **kwargs):
        t1 = time()
        result = func(*args, **kwargs)
        t2 = time()
        print(f'Function {func.__name__!r} executed in {(t2-t1):.4f}s')
        return result
    return wrap_func
  
  
@timer_func
def long_time(n):
    for i in range(n):
        for j in range(100000):
            i*j
  
  
long_time(5)


输出:

**********
Hello Geeks!
**********
**********
Bye Geeks!
**********

解释 :

在上面的例子中,my_decorator 是一个装饰器函数,它接受 func,一个函数对象作为参数。它定义了一个调用 func 的 wrapper_function 并执行它包含的代码。 my_decorator函数返回这个 wrapper_function。

那么,当我们在定义任何函数之前编写 @my_decorator 时会发生什么?考虑上面 say_hello函数的例子,它在定义时没有被任何装饰器装饰。我们仍然可以使用我们的装饰器来装饰它的输出,方法是调用 my_decorator函数并将 say_hello函数对象作为参数传递,它将返回一个带有两个打印语句的 wrapper_function,在两者之间调用 say_hello()函数。如果我们在 say_hello 对象本身中接收到这个修改后的函数,那么每当我们调用 say_hello() 时,我们都会得到修改后的输出。

我们可以在定义函数之前简单地编写@my_decorator,而不是编写这种复杂的语法,并将其余的工作留给Python解释器,如 say_bye函数。

使用装饰器的定时器函数

定时器函数是装饰器的应用之一。在下面的例子中,我们创建了一个 timer_func函数,它接受一个函数对象 func。在定时器函数内部,我们定义了 wrap_func ,它可以接受任意数量的参数 (*args) 和任意数量的关键字参数 (**kwargs) 传递给它。我们这样做是为了让我们的 timer_func 更加灵活。

在 wrap_func 的主体中,我们使用 time 模块的 time 方法记录了当前时间 t1,然后我们调用函数func 传递与 wrap_func 接收到的相同参数(*args, **kwargs)并存储返回值结果中。现在我们再次记录当前时间 t2 并打印记录时间之间的差异,即 { t2 – t1 } 精确到小数点后 4 位。这个 {t2 – t1} 是函数func 执行期间经过的时间。最后,我们又回到wrap_func函数中的结果值和返回timer_func函数这里面wrap_func函数。



我们还使用@timer_func 装饰器定义了 long_time函数,因此每当我们调用 long_time函数,它都会像这样调用:

timer_func(long_time)(5)

timer_func函数在调用时将 long_time 作为参数传递,返回一个 wrap_func函数,函数对象 func 开始指向 long_time函数。

wrap_func(5)

现在 wrap_func 将按上述说明执行并返回结果。

蟒蛇3

from time import time
  
  
def timer_func(func):
    # This function shows the execution time of 
    # the function object passed
    def wrap_func(*args, **kwargs):
        t1 = time()
        result = func(*args, **kwargs)
        t2 = time()
        print(f'Function {func.__name__!r} executed in {(t2-t1):.4f}s')
        return result
    return wrap_func
  
  
@timer_func
def long_time(n):
    for i in range(n):
        for j in range(100000):
            i*j
  
  
long_time(5)

输出:

Function 'long_time' executed in 0.0219s