时间它和部分



检查这个python代码:

 from functools import partial
 def summer(x, y):
      return x+y
 >>>partial(summer, 1, 2)
 <functools.partial object at 0x10e648628>

但是,当我通过部分时间时:

  import timeit
  min(timeit.repeat(partial(summer, 1, 2)))

它似乎用 x=1 和 y=2 来评估夏天。

我明白发生了什么吗?我用时间对吗?当我为每个参数传递值时,我如何部分评估夏天?

编辑:为了清楚起见,我添加了以下评论作为此问题的一部分。

我的问题是部分(夏季,1,2)不评估夏季。那么,为什么在timeit.repeat中调用它来评估夏天呢?

在 Python 中,function对象是"一等"对象。它们可以作为参数传递给函数,就像任何其他对象一样。在这种情况下, timeit.repeat传递函数对象partial(summer, 1, 2),以便稍后可以在repeat内部调用和计时函数对象。

partial(summer, 1, 2)本身是将函数(summer)作为参数传递给另一个函数(partial)的另一个例子。你想要传递函数对象是有道理的,因为你还不想调用summer。相反,您希望 partial 返回的函数对象有权访问summer以便稍后在调用该函数对象时可以调用它。


partial(summer, 1, 2)返回一个函数对象:

In [36]: partial(summer, 1, 2)
Out[36]: <functools.partial at 0x7ff31f0bd3c0>

如您所知,要调用该函数,您需要在函数后放置括号:

In [37]: partial(summer, 1, 2)()
Out[37]: 3

通常,当我使用timeit时,我会将语句stmt和设置作为字符串传递给timeit函数:

In [41]: func = partial(summer, 1, 2)
In [42]: timeit.repeat('func()', 'from __main__ import func')
Out[42]: [0.11481308937072754, 0.10448503494262695, 0.1048579216003418]

但是,您是正确的,也可以传递可调用对象(例如函数对象)作为第一个参数:

timeit.repeat(func) 

repeat将调用func并计时结果。您可以通过使用调试器单步执行代码来了解repeat如何处理这种情况,如下所示pdb

import pdb
pdb.set_trace()
timeit.repeat(func)

在第 140 行周围的timeit.py代码中,您将看到:

    elif callable(stmt):
        self.src = None
        if isinstance(setup, str):
            _setup = setup
            def setup():
                exec(_setup, global_ns, local_ns)

检查是否stmt,第一个参数是可调用的。如果是,则func设置为 stmt ,稍后调用func(源代码)。

def inner(_it, _timer, _func=func):
    setup()
    _t0 = _timer()
    for _i in _it:
        _func()       # <--- The function call happens here
    _t1 = _timer()
    return _t1 - _t0
return inner

相关内容

  • 没有找到相关文章

最新更新