Câu hỏi Lấy "tên toàn cầu 'foo' không được định nghĩa" với thời gian của Python


Tôi đang cố gắng tìm ra bao nhiêu thời gian để thực hiện 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 chuẩn cung cấp một mô-đun gọi là thời gian rằng purports làm 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 còn mới với Python và tôi không hoàn toàn hiểu tất cả các vấn đề phạm vi nó có, 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?


76
2018-02-15 23:15


gốc




Các câu trả lời:


Thay đổi dòng này:

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

Để đ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 quyền truy cập mô-đun thời gian cho các hàm 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 chỉ thử nghiệm nó trên máy của tôi và nó đã làm việc với những thay đổi.


83
2018-02-15 23:18



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 có cả hai cung cấp lệnh tôi muốn thời gian như một chuỗi và để nhập khẩu chủ yếu mô-đun cho nó hoạt động. - Kyle Cronin
Không gian tên Python là hoàn toàn điên rồ 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 cái trí óc đó không phải là thứ mà tôi tình cờ có được. Cảm ơn $ DEITY cho Ruby, trong trường hợp của tôi. - womble
womble, đây là một wart, không phải là một vấn đề không gian tên python chung. 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
@Gregg Liên kết không còn truy cập được (lỗi 404). Có gì trong cuộc thảo luận đó? - ovgolovin
những liên kết đó đều đã chết - endolith


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

19
2018-03-22 11:16



Hack này là tuyệt vời nếu bạn nếu không cần mã thiết lập phức tạp. - Luís Marques
Tốt hơn so với thay thế mã khởi động được đưa ra trong các trả lời khác (tức là tốt hơn so với t = timeit.Timer("foo()", "from __main__ import foo")). Đặc biệt nếu bạn muốn thử nghiệm một số chức năng khác nhau, nó sẽ tiết kiệm được rất nhiều đánh máy! - A.Sommerh
Tôi đã có khoảng 20 nhập khẩu, vì vậy vượt qua chúng như là một đối số được lộn xộn nhanh chóng. Hack này là tuyệt vời! - kramer65
Tuyệt quá! Trên python3 tuy nhiên bạn cần import builtins và 'nội trang .__ dict __. cập nhật (địa phương ())' - greole


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

Kể từ khi timeit không có công cụ của bạn trong phạm vi.


8
2018-02-15 23:22





Bạn có thể dùng globals=globals() 

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

Từ tài liệu:

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


7
2017-09-05 12:51



Chỉ hoạt động với Python 3. globals không phải là tham số cho Python 2 timeit - tony_tiger


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

sau đó khi bạn gọi hàm setup myfunc () 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 )

0
2018-06-01 22:45