Nhận "tên toàn cầu" foo "không được xác định" với thời gian của Python


92

Tôi đang cố gắng tìm hiểu xem cần bao nhiêu thời gian để thực thi một câu lệnh Python, vì vậy tôi đã xem trực tuyến và thấy rằng thư viện tiêu chuẩn cung cấp một mô-đun có tên là timeit có mục đích thực hiện chính xác điều đó:

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

Tuy nhiên, điều này tạo ra một lỗi:

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

Tôi vẫn chưa quen với Python và tôi không hiểu đầy đủ tất cả các vấn đề về phạm vi mà nó gặp phải, nhưng tôi không biết tại sao đoạn mã này không hoạt động. Có suy nghĩ gì không?

Câu trả lời:


93

Thay đổi dòng này:

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

Về điều này:

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

Kiểm tra liên kết bạn đã cung cấp ở dưới cùng.

Để cấp cho mô-đun thời gian quyền truy cập vào các chức năng bạn xác định, bạn có thể chuyển một tham số thiết lập có chứa câu lệnh nhập:

Tôi vừa thử nghiệm nó trên máy của mình và nó hoạt động với các thay đổi.


28
Nó hoạt động! Tuy nhiên, đây là một thiết kế giao diện khá ngu ngốc nếu tôi phải cung cấp lệnh mà tôi muốn thời gian dưới dạng chuỗi và nhập mô-đun chính để nó hoạt động.
Kyle Cronin

2
Không gian tên trong Python là một điều hoàn toàn điên rồ đối với tôi. Tôi cho rằng nó có ý nghĩa đối với một loại tâm trí nào đó, nhưng loại tâm trí đó không phải là thứ mà tôi tình cờ biết được. Cảm ơn $ DEITY vì Ruby, trong trường hợp của tôi.
womble

5
womble, đây là một mụn cóc, không phải là một vấn đề chung về không gian tên python. Chủ đề chính: writeonly.wordpress.com/2008/09/12/… có liên kết đến các cuộc thảo luận khác về điều này.
Gregg Lind

1
@Gregg Liên kết không thể truy cập được nữa (lỗi 404). Những gì trong cuộc thảo luận đó?
ovgolovin,

2
những liên kết đó đều đã chết
endolith.

25

Với Python 3, bạn có thể sử dụng globals=globals()

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

Từ tài liệu :

Một tùy chọn khác là chuyển globals()đến globalstham số, tham số này sẽ khiến mã được thực thi trong vùng tên chung hiện tại của bạn. Điều này có thể thuận tiện hơn so với việc chỉ định nhập khẩu riêng lẻ


3
Chỉ hoạt động cho Python 3. globalskhông phải là một tham số cho Python 2 củatimeit
tony_tiger

21

Bạn có thể thử hack này:

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
Bản hack này rất tuyệt nếu bạn cần mã thiết lập phức tạp.
Luís Marques

Tốt hơn thay thế mã khởi động được đưa ra trong các câu trả lời khác (tức là tốt hơn t = timeit.Timer("foo()", "from __main__ import foo")). Đặc biệt nếu bạn muốn kiểm tra một số chức năng khác nhau, nó sẽ tiết kiệm rất nhiều lần gõ!
A.Sommerh

1
Tôi có khoảng 20 nhập khẩu, vì vậy việc chuyển chúng như một cuộc tranh luận sẽ trở nên lộn xộn nhanh chóng. Bản hack này thật tuyệt vời!
kramer65

7
Tuyệt quá! Trên python3, tuy nhiên bạn cần import builtinsvà 'nội trang .__ dict __. Cập nhật (
local

Bạn có thể định thời gian cho nhiều hàm trong hàm Time () không?
edo101

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

Vì thời gian không có nội dung của bạn trong phạm vi.


0

thêm vào thiết lập của bạn "import thisfile;"

thì khi bạn gọi hàm thiết lập myfunc (), hãy sử dụng "thisfile.myfunc ()"

ví dụ: "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 )
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.