使用Python的timeit获取“未定义全局名称'foo'


92

我试图找出执行一条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()

但是,这会产生一个错误:

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

我对Python还是很陌生,我还不完全了解它的所有范围界定问题,但是我不知道为什么此代码片段不起作用。有什么想法吗?

Answers:


93

更改此行:

t = timeit.Timer("foo()")

对此:

t = timeit.Timer("foo()", "from __main__ import foo")

检查一下您在最底部提供的链接。

要使timeit模块可以访问您定义的功能,可以传递一个包含导入语句的设置参数:

我刚刚在我的机器上对其进行了测试,并且可以进行更改。


28
有用!但是,如果我必须同时提供希望作为字符串计时的命令并导入模块以使其工作,那么这将是一个非常愚蠢的界面设计。
凯尔·克罗宁

2
Python命名空间对我来说简直是疯了。我认为这对某种思维是有道理的,但是这种思维并不是我碰巧提出的。就我而言,感谢$ DEITY为Ruby。
09年

5
womble,这是一个疣,不是一般的python名称空间问题。主线程: writeonly.wordpress.com/2008/09/12/… 具有与此相关的其他讨论的链接。
格雷格·林德

1
@Gregg链接不再可用(错误404)。那个讨论是什么?
ovgolovin 2011年

2
这些链接都死了
endolith 2013年

25

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

t = timeit.Timer("foo()", globals=globals())

文档中

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


3
仅适用于Python 3。globals不是Python 2的参数timeit
tony_tiger

21

您可以尝试以下技巧:

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()

1
如果您另外需要复杂的设置代码,则此技巧非常有用。
路易·马克斯

比其他回复中给出的启动代码更好(即,优于t = timeit.Timer("foo()", "from __main__ import foo"))。特别是如果您要测试几个不同的功能,将节省很多输入时间!
A.Sommerh 2014年

1
我大约有20个导入,因此将它们作为参数传递很快就会变得混乱。这个骇客真棒!
kramer65 2014年

7
大!但是在python3上,您需要import builtins和'builtins .__ dict __。update(locals())'
greole 2016年

您可以在Time()函数中为多个函数计时吗?
edo101

8
t = timeit.Timer("foo()", "from __main__ import foo")

由于timeit在范围内没有您的东西。


0

在设置中添加“导入此文件;”

然后当您调用设置函数myfunc()时,请使用“ thisfile.myfunc()”

例如“ thisfile.py”

def myfunc():

 return 5

def testable(par):

 pass



t=timeit.timeit(stmt="testable(v)",setup="import thisfile; v=thisfile.myfunc();").repeat(10)

print( t )
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.