Python의 timeit으로 "글로벌 이름 'foo'가 정의되지 않았습니다."가져 오기


92

파이썬 문을 실행하는 데 걸리는 시간을 알아 내려고했는데, 온라인을 살펴본 결과 표준 라이브러리 가 정확히이를 수행한다고 주장하는 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()

그러나 다음과 같은 오류가 발생합니다.

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

저는 여전히 Python을 처음 접하고 있으며 모든 범위 지정 문제를 완전히 이해하지 못하지만이 코드 조각이 작동하지 않는 이유를 모르겠습니다. 이견있는 사람?

답변:


93

이 줄을 변경하십시오.

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

이에:

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

맨 아래에 제공 한 링크를 확인하십시오.

timeit 모듈에 정의한 함수에 대한 액세스 권한을 부여하려면 import 문이 포함 된 설정 매개 변수를 전달할 수 있습니다.

방금 내 컴퓨터에서 테스트했으며 변경 사항과 함께 작동했습니다.


28
효과가있다! 그러나 이것은 내가 원하는 명령을 문자열로 제공하고 그것이 작동 하도록 메인 모듈 을 가져와야한다면 꽤 어리석은 인터페이스 디자인 입니다.
Kyle Cronin

2
파이썬 네임 스페이스는 나에게 완전히 미친 짓이다. 나는 그것이 어떤 종류의 마음에 합리적이라고 생각하지만, 그런 종류의 마음은 내가 우연히 포즈를 취하는 것이 아닙니다. 제 경우에는 Ruby를 위해 $ DEITY에게 감사드립니다.
womble

5
womble, 이것은 일반적인 파이썬 네임 스페이스 문제가 아니라 사마귀입니다. 메인 스레드 : writeonly.wordpress.com/2008/09/12/… 에는 이에 대한 다른 토론에 대한 링크가 있습니다.
Gregg Lind

1
@Gregg 링크에 더 이상 액세스 할 수 없습니다 (오류 404). 그 토론에서 무엇이 있었습니까?
ovgolovin

2
해당 링크는 모두 죽었
endolith

25

Python 3에서는 다음을 사용할 수 있습니다. globals=globals()

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

로부터 문서 :

또 다른 옵션은 전달하는 것입니다 globals()받는 globals코드가 현재 글로벌 네임 스페이스 내에서 실행되게합니다 매개 변수. 개별적으로 가져 오기를 지정하는 것보다 더 편리 할 수 ​​있습니다.


3
Python 3에서만 작동합니다. globals파이썬 2의에없는 매개 변수timeit
tony_tiger

21

이 해킹을 시도 할 수 있습니다.

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
이 해킹은 복잡한 설정 코드가 필요한 경우 유용합니다.
Luís Marques 2011

다른 응답에 제공된 시작 코드 대안보다 낫습니다 (즉,보다 낫습니다 t = timeit.Timer("foo()", "from __main__ import foo")). 특히 여러 다른 기능을 테스트하려는 경우 많은 타이핑을 절약 할 수 있습니다!
A.Sommerh

1
나는 약 20 개의 수입품을 가지고있어서 그것들을 인수로 전달하는 것은 금방 지저분해진다. 이 해킹은 굉장합니다!
kramer65

7
큰! 그러나 python3에서는 import builtins'builtins .__ dict __. update (locals ())'가 필요합니다.
greole

Time () 함수에서 여러 함수의 시간을 측정 할 수 있습니까?
edo101

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

시간 이후로 그것은 범위에 당신의 물건을 가지고 있지 않습니다.


0

설정에 추가 "이 파일 가져 오기;"

그런 다음 설정 함수 myfunc ()를 호출 할 때 "thisfile.myfunc ()"를 사용하십시오.

예 : "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 )
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.