2013-07-27 31 views
7

Khi xem qua danh sách các chức năng Python built-in, tôi đấu tranh với sự hiểu biết về tính hữu ích của phương pháp compile. Tất cả các ví dụ tôi có thể tìm thấy điểm đến một "thế giới hello" đơn giản. Nó có ý nghĩa những gì, nhưng không phải khi sử dụng.Việc sử dụng chính Python được xây dựng trong 'biên dịch' là gì?

Đây có phải là phương thức tương tự mà Python sử dụng để tạo tệp .pyc không?

Điều này có thể được sử dụng để loại bỏ một số tính chất động của Python để cải thiện hiệu suất trên một số mã nhất định không? (Biết rõ rằng một module trong C là con đường để đi module biên dịch sẵn.)

Trả lời

6

Từ đây: What's the difference between eval, exec, and compile in Python?:

compile là một phiên bản cấp thấp hơn của execeval. Nó không thực hiện hoặc đánh giá các câu lệnh hoặc biểu thức của bạn, nhưng trả về một đối tượng mã có thể thực hiện nó. Các chế độ như sau:

  1. compile(string, '', 'eval') trả về đối tượng mã đã được thực hiện mà bạn đã thực hiện eval(string). Lưu ý rằng bạn không thể báo cáo sử dụng ở chế độ này; chỉ một biểu thức (duy nhất) là hợp lệ.
  2. compile(string, '', 'exec') trả về đối tượng mã đã được thực hiện mà bạn đã thực hiện exec(string). Bạn có thể sử dụng bất kỳ số báo cáo nào ở đây.
  3. compile(string, '', 'single') giống như chế độ exec nhưng sẽ bỏ qua mọi thứ ngoại trừ câu lệnh đầu tiên. Lưu ý rằng tuyên bố if/else có kết quả được coi là một câu lệnh duy nhất.

UPDATE:

Khi biên dịch Python?

Thông thường, bạn biên dịch Python để tận dụng hiệu suất. Mã biên dịch có thời gian khởi động nhanh hơn nhiều vì nó không phải được biên soạn, nhưng nó không chạy nhanh hơn.

Đáng chú ý nhất, bạn sẽ sử dụng compile nếu bạn muốn chuyển đổi mã thành bytecode bằng tay. Điều này đưa ra một câu hỏi quan trọng, nhưng thích hợp khác lý do tại sao làm điều này?

Như tham chiếu trong này magnificent article:

nếu bạn muốn sử dụng exec và bạn có kế hoạch thực thi mã rằng hơn một lần, chắc chắn bạn biên dịch nó thành bytecode đầu tiên và sau đó thực hiện rằng bytecode chỉ và chỉ trong một từ điển mới là không gian tên.

Đáng chú ý đặc biệt là thế này:

Bây giờ làm sao nhanh hơn nhiều đang thực hiện bytecode trên tạo ra bytecode và thực hiện điều đó không?:

$ python -mtimeit -s 'mã = "a = 2; b = 3; c = a * b"' 'mã exec' 10000 vòng, tốt nhất là 3: 22,7 USEC mỗi vòng lặp

$ python -mtimeit -s 'code = compile ("a = 2; b = 3; c = a * b",
"", "exec")' 'mã exec' 1000000 vòng, tốt nhất là 3: 0.765 usec trên mỗi vòng

32 lần nhanh như một ví dụ mã rất ngắn. Nó trở nên tồi tệ hơn rất nhiều bạn càng có nhiều mã. Tại sao lại như vậy? Bởi vì phân tích mã Python và chuyển đổi thành Bytecode là một hoạt động tốn kém so với việc đánh giá mã byte. Điều đó tất nhiên cũng ảnh hưởng đến execfile hoàn toàn không sử dụng bộ đệm bytecode, nên làm như thế nào. Nó sẽ không kiểm tra một cách kỳ diệu nếu có tệp .pyc nếu bạn đang chuyển đường dẫn đến tệp foo.py.

+0

Đây là những gì tôi đã thu thập, nhưng vẫn chưa rõ khi nào/tại sao nên sử dụng. Điều duy nhất mà đến với tâm trí sẽ kiểm tra nhanh để xem nếu có bất kỳ lỗi cú pháp trước khi gọi một 'eval'/'exec'. –

+0

@AdamLewis, lời xin lỗi của tôi. Đã cập nhật. – jrd1

+1

Cập nhật tuyệt vời. Tôi đã có một linh cảm rằng nó đã được hướng tới chỉ thực sự hữu ích khi sử dụng 'exec' được xây dựng trong. Cảm ơn đã dành thời gian để làm sáng tỏ một số chủ đề. –

2

Để trả lời bản chất động, không, không thực sự. Đối tượng mã kết quả vẫn được giải thích; cùng bytecode vẫn chạy.

Cách sử dụng biên dịch() (và tạo mã) hữu ích/ấn tượng nhất mà tôi đã thấy là trong Jinja2. Nó thực sự tạo ra mã Python từ các mẫu của bạn, sau đó sử dụng biên dịch để nó chạy ở tốc độ 'native' (== interpreter), nếu điều đó có ý nghĩa.

https://github.com/mitsuhiko/jinja2/blob/master/jinja2/environment.py#L506

Ngược lại với, nói, django.template, mà không tra cứu biến, vv trong "không gian người dùng" (một lần nữa, có thể nói - ẩn dụ là loại kỳ lạ).

https://github.com/django/django/blob/master/django/template/base.py#L752

+0

Tôi đã sử dụng cả django và jinja, nhưng chưa bao giờ đào sâu vào hệ thống mẫu trước đây. Tôi đồng ý rằng đó là cách khá để xử lý các mẫu. Có lẽ đây là một phần của lý do tôi đã sử dụng jinga như hệ thống templating trong django :) –

Các vấn đề liên quan