2013-08-14 58 views
10

Tôi muốn sử dụng tuyệt vời line_profiler, nhưng chỉ một số thời gian. Để làm cho nó hoạt động, tôi thêmlập hồ sơ bằng python bằng cách sử dụng line_profiler - cách thông minh để xóa báo cáo @profile khi đang di chuyển?

@profile 

trước mọi cuộc gọi hàm, ví dụ:

@profile 
def myFunc(args): 
    blah 
    return 

và thực hiện

kernprof.py -l -v mycode.py args 

Nhưng tôi không muốn phải đưa @profile trang trí bằng tay mỗi lần, vì hầu hết thời gian tôi muốn thực thi mã mà không có họ, và Tôi nhận được một ngoại lệ nếu tôi cố gắng bao gồm chúng, ví dụ

mycode.py args 

Có một phương tiện hạnh phúc mà tôi có thể tự động có trang trí loại bỏ dựa trên một số điều kiện chuyển đổi/tranh luận, mà không cần phải làm những việc bằng tay và/hoặc sửa đổi mỗi chức năng quá nhiều?

+0

Tôi tự hỏi mình có thực sự cần phải cấu hình thường xuyên đến mức cần hỗ trợ không. Tôi không nói bạn làm hay không, vì vậy bạn không cần phải trả lời. Tôi chỉ tìm thấy trường hợp sử dụng một chút đáng ngạc nhiên. – msw

+0

Mã mất một thời gian dài (giờ tại thời điểm này ...) để thực hiện, vì vậy bây giờ tôi muốn giết hai con chim với một hòn đá trong việc nhận được kết quả và lược tả cùng một lúc. Tôi cho rằng tôi thấy hồ sơ như là một quá trình liên tục (vì tôi mới/hứng thú với nó), vì vậy tôi sẽ không sử dụng nó trong các hàm (nhiều), khai báo nó và loại bỏ tất cả các trang trí. – jtlz2

+0

Tôi sẽ không để cho một cái gì đó mất nhiều giờ mà không [* cố gắng này *] (http://stackoverflow.com/a/4299378/23771). Nó chi phí không có gì và cho bạn biết chính xác những gì đang xảy ra. –

Trả lời

13

Thay vì xóa dòng trang trí @profile, hãy cung cấp phiên bản không có phiên bản chuyển tiếp của riêng bạn.

Bạn có thể thêm đoạn mã sau vào dự án của bạn ở đâu đó:

import __builtin__ 

try: 
    __builtin__.profile 
except AttributeError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 
    __builtin__.profile = profile 

nhập này trước khi bất kỳ mã sử dụng @profile trang trí và bạn có thể sử dụng mã có hoặc không có dòng profiler là tích cực.

Bởi vì trình trang trí giả là chức năng chuyển tiếp, hiệu suất thực thi không bị ảnh hưởng (chỉ hiệu suất nhập là mọi ảnh hưởng nhẹ đến vậy).

Nếu bạn không thích rối tung với các bản dựng sẵn, bạn có thể biến nó thành một mô-đun riêng biệt; nói profile_support.py:

import __builtin__ 

try: 
    profile = __builtin__.profile 
except AttributeError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 

(không phân-__builtin__.profile) và sử dụng from profile_support import profile trong bất kỳ mô-đun mà sử dụng @profile trang trí.

+0

Cảm ơn rất lớn - và để trả lời nhanh chóng! Tôi đã đi với tùy chọn thứ hai và nó hoạt động rực rỡ. – jtlz2

+1

Trong Python3, bạn cần phải thay thế '__builtin__' bằng nội trang dựng sẵn. Nhưng đó chỉ là tìm kiếm và thay thế, mọi thứ khác vẫn hoạt động như cũ. –

1

Tôi đang sử dụng phiên bản sửa đổi sau đây với Python 3,4

try: 
    import builtins 
    profile = builtins.__dict__['profile'] 
except KeyError: 
    # No line profiler, provide a pass-through version 
    def profile(func): return func 
3

Một nhận xét rằng phát triển để trở thành một biến thể của @Martijin Pieters câu trả lời.

Tôi hoàn toàn không muốn liên quan đến __builtin__. W/o một bình luận, nó sẽ là thực tế không thể cho người khác để đoán rằng line_profiler là có liên quan, w/o một ưu tiên biết điều này.

Nhìn vào kernprofline 199, nó đủ để khởi tạo LineProfiler.

try: 
    from line_profiler import LineProfiler 
    profile = LineProfiler() 
except ImportError: 
    def profile(func): 
     return func 

Nhập khẩu (rõ ràng) is better hơn thay đổi toàn cầu builtins (ngầm). Nếu các trình trang trí hồ sơ là vĩnh viễn, thì nguồn gốc của chúng phải rõ ràng trong chính mã.

Khi có mặt của line_profiler, cách tiếp cận trên sẽ bao bọc các chức năng được trang trí với trình biên dịch trên mọi lần chạy, bất kể chạy theo kernprof. Tác dụng phụ này có thể không mong muốn.

3

Bạn không cần phải nhập khẩu __builtins__/builtins hoặc LineProfiler ở tất cả, bạn chỉ có thể dựa vào một NameError khi cố gắng để tra cứu profile:

try: 
    profile 
except NameError: 
    profile = lambda x: x 

Tuy nhiên điều này cần phải được đưa vào tất cả các file mà sử dụng profile, nhưng nó không (vĩnh viễn) thay đổi trạng thái toàn cục (nội trang) của Python.