web-dev-qa-db-fra.com

Obtenir "le nom global 'foo' n'est pas défini" avec le timeit de Python

J'essaie de savoir combien de temps il faut pour exécuter une instruction Python. J'ai donc cherché en ligne et découvert que la bibliothèque standard fournissait un module appelé timeit qui prétend faire exactement cela:

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

Cependant, cela produit une erreur:

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

Je ne suis toujours pas nouveau sur Python et je ne comprends pas bien tous les problèmes de portée qu’il a, mais je ne sais pas pourquoi cet extrait ne fonctionne pas. Des pensées?

80
Kyle Cronin

Changer cette ligne:

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

Pour ça:

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

Consultez le lien que vous avez fourni tout en bas.

Pour permettre au module timeit d'accéder aux fonctions que vous définissez, vous pouvez passer un paramètre de configuration contenant une instruction d'importation:

Je viens de le tester sur ma machine et cela a fonctionné avec les changements.

88
Paolo Bergantino

Vous pouvez essayer ce 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()
19
Luka Zakrajšek

Avec Python 3, vous pouvez utiliser globals=globals() 

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

De la documentation :

Une autre option consiste à passer globals() au paramètre globals, qui Le code sera exécuté dans votre fichier global actuel espace de noms. Cela peut être plus pratique que de spécifier individuellement importations

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

Depuis le temps, il n'a pas vos affaires dans la portée.

8
dwc

ajoutez dans votre configuration "import thisfile;"

alors quand vous appelez la fonction d'installation myfunc () utilisez "thisfile.myfunc ()"

par exemple "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 )
0
mist42nz