Python Timeit and "global name ... not defined"

I have a problem with timit function to optimize code. For example, I am writing functions with parameters in a file, let it contain myfunctions.py :

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

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

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

Y0 not calculated, and even if I comment out the line print Y0 , a global name 'myfunctions' is not defined .

If I specify the setting using the command

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

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

Does anyone know how to solve this? Many thanks.

+6
source share
2 answers

You need the setup parameter. Try:

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

The reason Y0 is undefined is that you have determined what is in the string, but at the time of parsing at the start of execution, the string has not yet been evaluated to bring the variable to life. So put Y0 = 0 somewhere at the top of your script to define it in advance.

All external functions and variables must be assigned to Timer using the setup argument. Therefore, you need "import myfunctions; X0 = 1" as the setting.

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 

See how I used "X0 = %i" % (X0,) to pass the actual value of the external variable X0.

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 timeit able to modify your variables, you should not pass strings to them. More conveniently, you can transfer calls to him. You must pass a callable that will change your desired variable. Then you do not need to setup . Take a 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 can see, I put print Y0 after print t.timeit() , since you cannot change its value before execution!

+4
source

Source: https://habr.com/ru/post/905091/


All Articles