2012-01-04 11 views
6

Tengo un problema con la función timit para la optimización del código. Por ejemplo, puedo escribir funciones con parámetros en un archivo, vamos a llamarlo myfunctions.py que contiene:Python Timeit y "nombre global ... no está definido"

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

y probar esta función en un segundo archivo test.py en el que llama a la función de temporizador para poner a prueba el rendimiento del código (en obviamente más compleja problemas) que contienen:

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

el Y0 no se calcula, e incluso si comento print Y0 línea se produjo el error global name 'myfunctions' is not defined.

Si se especifica la configuración con el comando

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

ahora se produjo el error global name 'X0' is not defined.

¿Alguien sabe cómo solucionar esto? Muchas gracias.

+0

Posible duplicado de [Obtener "nombre global 'foo' no está definido" con el tiempo de Python] (https://stackoverflow.com/questions/551797/getting-global-name-foo-is-not-defined-with -pythons-timeit) – sds

Respuesta

6

Necesita el parámetro setup. Proveedores:

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

Como mencioné en la pregunta, esto devuelve un error "nombre global 'X0' no está definido" – cedm34

+0

@ cedm34 Ver la actualización –

+1

El error global ha desaparecido bien.Pero esto no crea el valor Y0. ¿Hay una solución para? – cedm34

4

La razón de Y0 siendo indefinido es que usted ha definido que en una cadena, pero en tiempo de análisis en el inicio de la ejecución de la cadena no es evaluado para llevar la variable en la vida. Así que ponga un Y0 = 0 en algún lugar en la parte superior de su script para tenerlo definido de antemano.

Todas las funciones y variables externas se deben dar a Timer usando su argumento setup. Por lo tanto, necesita "import myfunctions; X0 = 1" como parámetro de configuración.

Esto funcionará:

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 

Mira cómo solía "X0 = %i" % (X0,) a pasar en el valor real de la variable X0 externa.

Otra cosa que podría querer saber es que si hay algunas funciones en el archivo principal que se desea utilizar en timeit, puede hacer timeit ellos reconocen al pasar from __main__ import * como segundo argumento.


Si desea timeit para poder modificar las variables, entonces no debería pasar cadenas a ellos. Más convenientemente puedes pasar callables a él. Debería pasar un invocable que cambie la variable deseada. No necesita setup y luego. Mira:

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 

Como se ve, puse print Y0despuésprint t.timeit() ya que la ejecución antes de que no puede haber cambiado su valor!

Cuestiones relacionadas