Python Timeit and “global name ... is not defined”
Asked Answered
W

2

7

I have a problem with timit function for code optimization. For example, I writing functions with parameters in a file, let's call it myfunctions.py containing :

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

and I test this function in a second file test.py where I call the timer function to test code performance (in obviously more complex problems!) containing :

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

The Y0 is not calculated, and even if I comment print Y0 line the error global name 'myfunctions' is not defined occured.

If I specify the setup with the command

t = Timer("Y0 = myfunctions.func1(X0)","import myfunctions")

now the error global name 'X0' is not defined occurred.

Is someone know how to solve this ? Many thanks.

Widthwise answered 4/1, 2012 at 12:46 Comment(1)
Possible duplicate of Getting "global name 'foo' is not defined" with Python's timeitSudoriferous
P
6

You need setup parameter. Try:

Timer("Y0 = myfunctions.func1(X0)", setup="import myfunctions; X0 = 1")
Pearlypearman answered 4/1, 2012 at 12:49 Comment(2)
As I mentionned in the question, this return an error "global name 'X0' is not defined"Widthwise
The global error have well disapeared. But this not create the Y0 value. Is there a solution for ?Widthwise
T
4

The reason for Y0 being undefined is that you have defined that in a string, but at parse time in the beginning of the execution the string is not evaluated yet to bring the variable into life. So put an Y0 = 0 somewhere at the top of your script to have it defined beforehand.

All external functions and variables must be given to Timer using its setup argument. So you need "import myfunctions; X0 = 1" as the setup parameter.

This will work:

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

Look how I used "X0 = %i" % (X0,) to pass in the real value of the external X0 variable.

Another thing you might want to know is that if there are any functions in your main file that you want to use in timeit, you can make timeit recognize them by passing from __main__ import * as the second argument.


If you want timeit to be able to modify your variables, then you shouldn't pass strings to them. More conveniently you can pass callables to it. You should pass a callable that changes your desired variable. You don't need setup then. Look:

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

As you see, I put print Y0 after print t.timeit() since before execution you can't have its value changed!

Tiffinytiffy answered 4/1, 2012 at 16:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.