使用Python的timeit来定义"全局名称'foo'"

Kyl*_*nin 83 python scope timeit

我试图找出执行Python语句需要多长时间,所以我在线查看并发现标准库提供了一个名为timeit的模块,其目的是做到这一点:

import timeit

def foo():
    # ... contains code I want to time ...

def dotime():
    t = timeit.Timer("foo()")
    time = t.timeit(1)
    print "took %fs\n" % (time,)

dotime()
Run Code Online (Sandbox Code Playgroud)

但是,这会产生错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in dotime
  File "/usr/local/lib/python2.6/timeit.py", line 193, in timeit
    timing = self.inner(it, self.timer)
  File "<timeit-src>", line 6, in inner
NameError: global name 'foo' is not defined
Run Code Online (Sandbox Code Playgroud)

我还是Python新手,我不完全理解它所有的范围问题,但我不知道为什么这个片段不起作用.有什么想法吗?

Pao*_*ino 91

改变这一行:

t = timeit.Timer("foo()")
Run Code Online (Sandbox Code Playgroud)

对此:

t = timeit.Timer("foo()", "from __main__ import foo")
Run Code Online (Sandbox Code Playgroud)

查看最底部提供的链接.

要使timeit模块能够访问您定义的函数,可以传递包含import语句的setup参数:

我只是在我的机器上测试它,它适用于变化.

  • 有用!但是,如果我必须同时提供我希望作为字符串输入的命令并导入__main__模块以使其工作,那么这是一个非常愚蠢的界面设计. (26认同)
  • womble,这是一个疣,而不是一般的python命名空间问题.主要内容:http://writeonly.wordpress.com/2008/09/12/using-python-timeit-to-time-functions/有关于此的其他讨论的链接. (5认同)
  • 对于Python 3,使用@user2314737的解决方案 `t = timeit.Timer("foo()", globals=globals()) ` (4认同)
  • Python命名空间对我来说是完全疯狂的.我认为这对某种心灵来说是有意义的,但这种心灵并不是我想要的.感谢$ DEITY for Ruby,就我而言. (2认同)
  • 那些链接都死了 (2认同)

小智 20

你可以试试这个黑客:

import timeit

def foo():
    print 'bar'

def dotime():
    t = timeit.Timer("foo()")
    time = t.timeit(1)
    print "took %fs\n" % (time,)

import __builtin__
__builtin__.__dict__.update(locals())

dotime()
Run Code Online (Sandbox Code Playgroud)

  • 大!但是在python3上你需要`import builtins`和'builtins .__ dict __.update(locals())' (5认同)
  • 如果您需要复杂的设置代码,那么这个技巧非常有用。 (2认同)

use*_*737 18

使用Python 3,您可以使用 globals=globals()

t = timeit.Timer("foo()", globals=globals())
Run Code Online (Sandbox Code Playgroud)

文档:

另一种选择是传递globals()globals参数,这将导致代码在当前的全局命名空间中执行.这比单独指定导入更方便

  • 仅适用于Python 3.`globals`不是Python 2的`timeit`的参数 (3认同)

dwc*_*dwc 8

t = timeit.Timer("foo()", "from __main__ import foo")
Run Code Online (Sandbox Code Playgroud)

由于timeit没有你的东西在范围内.