2009-02-15 6 views
73

Próbuję dowiedzieć się, ile czasu potrzeba na wykonanie instrukcji Pythona, więc sprawdziłem online i odkryłem, że standardowa biblioteka udostępnia moduł o nazwie timeit. że rzekomo dokładnie to zrobić:Uzyskiwanie "globalnej nazwy" foo "nie jest zdefiniowane" z czasem Pythona

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

jednak to powoduje błąd:

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 

wciąż jestem nowy w Pythonie i nie w pełni zrozumieć wszystkie zagadnienia zakresu studium ma, ale Nie wiem, dlaczego ten fragment nie działa. jakieś pomysły?

Odpowiedz

82

Zmiana ta linia:

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

do tego:

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

sprawdzić link podałeś na samym dole.

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

Właśnie przetestowałem to na moim komputerze i zadziałało ze zmianami.

+20

To działa! Jest to jednak dość głupi projekt interfejsu, jeśli muszę zarówno dostarczyć komendę, którą chciałbym wykonać jako ciąg, jak i zaimportować moduł __main__, aby działał. –

+2

Python namespacing jest dla mnie kompletnym szaleństwem. Zakładam, że ma to sens dla pewnego rodzaju umysłu, ale ten rodzaj umysłu nie jest taki, jaki mi się wydaje. Dziękuję $ DEITY za Ruby, w moim przypadku. – womble

+4

womble, to jest brodawka, a nie ogólny problem z pythonową przestrzenią nazw. Główny wątek: http://writeonly.wordpress.com/2008/09/12/using-python-timeit-to-time-functions/ zawiera linki do innych dyskusji na ten temat. –

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

Ponieważ timeit nie ma twoich rzeczy w zakresie.

18

Można spróbować tej 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

Ten hack jest świetny, jeśli w przeciwnym razie potrzebujesz skomplikowanego kodu konfiguracji. –

+0

Lepsza niż alternatywa kodu startowego podana w innych odpowiedziach (tj. Lepsza niż 't = timeit.Timer (" foo() "," od __main__ import foo ")'). Specjalnie, jeśli chcesz przetestować kilka różnych funkcji, zaoszczędzisz wiele pisania! –

+1

Mam około 20 importów, więc przekazanie ich jako argumentu staje się niechlujne. Ten hack jest niesamowity! – kramer65

0

dodać do konfiguracji "importowej tenplik,"

wtedy, gdy nazywają myfunc funkcji setup() użyć "thisfile.myfunc()"

np "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

można użyć globals=globals()

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

Z 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

Działa tylko w języku Python 3. 'globals' nie jest parametrem dla' timeit' w Pythonie 2 –

Powiązane problemy