如何在装饰器中使用 timeit 模块

How do I use timeit module inside a decorator

我正在创建一个装饰器,主要用于 timeit 它装饰的任何函数。而且我做对不了。投掷 max recursion depth error。有人能帮我理解为什么会这样以及如何实现这个 timeit 实现。 我不想使用 time 模块

import timeit
from functools import wraps


def tool(func):
    """Include debug statement and timeit setup"""
    @wraps(func)
    def wrapper(*args):
        print func.__doc__, args,
        res = func(*args)
        print res
        CODE = "func{args}".format(args=args)
        times = timeit.repeat(
            stmt=CODE,
            setup="from __main__ import {func} as func".format(func=func.__name__),
            repeat=3, number=10000)
        print times
    return wrapper

我提到的问题是在设置中,执行导入会得到已经修饰过的函数,当再次执行时执行导入并获取修饰过的函数,然后继续执行导入等等,直到失败向上堆栈...我们不希望那样。

timeit 模块也可以将函数作为它的 stmt,所以只需构建一个 lambda 函数就可以解决问题,我们可以这样使用 undercoated 函数

The stmt and setup parameters can also take objects that are callable without arguments. This will embed calls to them in a timer function that will then be executed by timeit(). Note that the timing overhead is a little larger in this case because of the extra function calls.

import timeit
from functools import wraps
    
def tool(func):
    """Include debug statement and timeit setup"""
    @wraps(func)
    def wrapper(*args):
        print(func.__doc__, args)
        res = func(*args)
        print(res)
        times = timeit.repeat(
            stmt=lambda: func(*args),
            repeat=3, number=10000)
        print(times)
    return wrapper

和快速测试

>>> @tool
def fun():
    return 42
>>> fun()
None ()
42
[0.0013318000000026586, 0.0013294000000314554, 0.0013452000000597764]
>>>