Python Timeit和“全局名称......未定义”

时间:2012-01-04 12:46:35

标签: python global-variables timeit

我有一个用于代码优化的timit函数的问题。例如,我在文件中编写带参数的函数,让我们将其称为myfunctions.py,其中包含:

def func1(X):
    Y = X+1
    return Y

我在第二个文件test.py中测试了这个函数,我调用了timer函数来测试代码性能(显然是更复杂的问题!),其中包含:

import myfunctions
X0 = 1
t = Timer("Y0 = myfunctions.func1(X0)")
print Y0
print t.timeit()

Y0未计算,即使我对print Y0发表评论,也会发生错误global name 'myfunctions' is not defined

如果我使用命令

指定设置
t = Timer("Y0 = myfunctions.func1(X0)","import myfunctions")

现在发生错误global name 'X0' is not defined

有人知道如何解决这个问题吗?非常感谢。

2 个答案:

答案 0 :(得分:6)

您需要setup参数。尝试:

Timer("Y0 = myfunctions.func1(X0)", setup="import myfunctions; X0 = 1")

答案 1 :(得分:4)

Y0未定义的原因是你已经在字符串中定义了它,但是在执行开始时的解析时,字符串还没有被评估以使变量生效。因此,在脚本顶部的某处放置一个Y0 = 0,以便事先定义它。

必须使用Timer参数将所有外部函数和变量赋予setup。因此,您需要"import myfunctions; X0 = 1"作为设置参数。

这将有效:

from timeit import Timer
import myfunctions
X0 = 1
Y0 = 0     #Have Y0 defined
t = Timer("Y0 = myfunctions.func1(X0)", "import myfunctions; X0 = %i" % (X0,))
print t.timeit()
print Y0

看看我如何使用"X0 = %i" % (X0,)传递外部X0变量的实际值。

您可能想要了解的另一件事是,如果您要在timeit中使用主文件中的任何功能,则可以timeit通过传递from __main__ import *来识别它们作为第二个论点。


如果您希望timeit能够修改变量,则不应将字符串传递给它们。更方便的是你可以通过callables。您应该传递一个可更改所需变量的callable。那你不需要setup。看:

from timeit import Timer
import myfunctions

def measure_me():
    global Y0    #Make measure_me able to modify Y0
    Y0 = myfunctions.func1(X0)

X0 = 1
Y0 = 0     #Have Y0 defined
t = Timer(measure_me)
print t.timeit()
print Y0

如您所见,我在 print Y0之后添加了print t.timeit() ,因为在执行之前您无法更改其值!