Python Timeit和“全局名称。。。未定义“

2024-04-20 06:53:54 发布

您现在位置:Python中文网/ 问答频道 /正文

代码优化的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

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


Tags: 文件函数namepyimportis错误not
2条回答

未定义Y0的原因是,您已经在字符串中定义了它,但是在执行开始时的解析时间,字符串还没有计算出来以使变量生效。因此,在脚本的顶部放一个Y0 = 0来预先定义它。

所有外部函数和变量必须使用其setup参数赋给Timer。所以需要"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中使用,您可以通过将from __main__ import *作为第二个参数来使timeit识别它们。


如果希望timeit能够修改变量,则不应向它们传递字符串。更方便的是,您可以将可调用项传递给它。您应该传递一个更改所需变量的可调用函数。那你不需要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()之后,因为在执行之前您不能更改它的值!

您需要setup参数。尝试:

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

相关问题 更多 >