Getting "global name 'foo' is not defined" with Python's timeit

PythonScopeTimeit

Python Problem Overview


I'm trying to find out how much time it takes to execute a Python statement, so I looked online and found that the standard library provides a module called timeit that purports to do exactly that:

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

However, this produces an error:

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

I'm still new to Python and I don't fully understand all the scoping issues it has, but I don't know why this snippet doesn't work. Any thoughts?

Python Solutions


Solution 1 - Python

Change this line:

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

To this:

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

Check out the link you provided at the very bottom.

> To give the timeit module access to functions you define, you can pass a setup parameter which contains an import statement:

I just tested it on my machine and it worked with the changes.

Solution 2 - Python

With Python 3, you can use globals=globals()

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

From the documentation:

> Another option is to pass globals() to the globals parameter, which > will cause the code to be executed within your current global > namespace. This can be more convenient than individually specifying > imports

Solution 3 - Python

You can try this hack:

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

Solution 4 - Python

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

Since timeit doesn't have your stuff in scope.

Solution 5 - Python

add into your setup "import thisfile; "

then when you call the setup function myfunc() use "thisfile.myfunc()"

eg "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 )

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKyle CroninView Question on Stackoverflow
Solution 1 - PythonPaolo BergantinoView Answer on Stackoverflow
Solution 2 - Pythonuser2314737View Answer on Stackoverflow
Solution 3 - PythonLuka ZakrajšekView Answer on Stackoverflow
Solution 4 - PythondwcView Answer on Stackoverflow
Solution 5 - Pythonmist42nzView Answer on Stackoverflow