2009-02-15 10 views
73

Sto cercando di scoprire quanto tempo ci vuole per eseguire un'istruzione Python, quindi ho cercato online e ho scoperto che la libreria standard fornisce un modulo chiamato timeit che pretende di fare esattamente questo:Ottenere "nome globale 'pippo' non è definito" con Python's timeit

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

Tuttavia, questo produce un errore:

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 

sono ancora nuovo a Python e non capisco pienamente tutte le questioni di ambito che ha, ma Non so perché questo frammento non funzioni. qualche idea?

risposta

82

Modifica questa linea:

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

A tal:

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

controllare il link che hai fornito in fondo.

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

L'ho appena testato sulla mia macchina e ha funzionato con le modifiche.

+20

Funziona! Tuttavia, questa è un'interfaccia piuttosto stupida se devo fornire sia il comando che desidero trascorrere il tempo come una stringa sia importare il modulo __main__ affinché funzioni. –

+2

Il namespace di Python è una pazzia per me. Presumo che abbia senso per un certo tipo di mente, ma quel tipo di mente non è uno che mi capita di possedere. Grazie a $ DEITY per Ruby, nel mio caso. – womble

+4

womble, questo è un verruca, non un problema generale dello spazio dei nomi Python. Thread principale: http://writeonly.wordpress.com/2008/09/12/using-python-timeit-to-time-functions/ ha collegamenti ad altre discussioni su questo. –

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

Dal momento che il tempo non ha le tue cose in ambito.

18

Si può provare questo 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() 
+1

Questo hack è ottimo se altrimenti avresti bisogno di un codice di configurazione complesso. –

+0

Migliore del codice di avvio alternativo fornito in altre risposte (ad esempio meglio di 't = timeit.Timer (" foo() "," da __main__ import foo ")'). Specialmente se vuoi testare diverse funzioni, risparmierai molte digitazioni! –

+1

Ho circa 20 importazioni, quindi passarle come argomento diventa un po 'complicato. Questo hack è fantastico! – kramer65

0

aggiungere nella vostra configurazione "import thisfile;"

poi quando si chiama la funzione di impostazione myFunc() usano "thisfile.myfunc()"

ad esempio "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) 
4

È possibile utilizzare globals=globals()

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

Dal 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

+1

Works for Python 3 only. 'globals' non è un parametro per' timeit' di Python 2 –

Problemi correlati