Python có một trình biên dịch! Bạn không nhận thấy nó vì nó chạy tự động. Mặc dù vậy, bạn có thể nói rằng nó ở đó: nhìn vào các tệp .pyc
(hoặc .pyo
nếu bạn đã bật trình tối ưu hóa) được tạo cho các mô-đun mà bạn import
.
Ngoài ra, nó không biên dịch thành mã của máy gốc. Thay vào đó, nó biên dịch thành mã byte được sử dụng bởi một máy ảo. Máy ảo là một chương trình được biên dịch. Điều này rất giống với cách Java hoạt động; Thực tế, tương tự như vậy, có một biến thể Python ( Jython ) biên dịch thành mã byte của Máy ảo Java! Ngoài ra còn có IronPython , trình biên dịch sang CLR của Microsoft (được sử dụng bởi .NET). (Trình biên dịch mã byte Python bình thường đôi khi được gọi là CPython để phân tán nó khỏi các lựa chọn thay thế này.)
C ++ cần phơi bày quá trình biên dịch của nó vì bản thân ngôn ngữ chưa hoàn chỉnh; nó không chỉ định mọi thứ mà trình liên kết cần biết để xây dựng chương trình của bạn và cũng không thể chỉ định các tùy chọn biên dịch một cách hợp lý (một số trình biên dịch cho phép bạn sử dụng #pragma
, nhưng đó không phải là tiêu chuẩn). Vì vậy, bạn phải thực hiện phần còn lại của công việc với makefiles và có thể là auto hell (autoconf / automake / libtool). Đây thực sự chỉ là một sự tiếp quản từ cách C đã làm nó. Và C đã làm theo cách đó bởi vì nó làm cho trình biên dịch trở nên đơn giản, đó là một lý do chính khiến nó trở nên phổ biến (bất kỳ ai cũng có thể tạo ra một trình biên dịch C đơn giản trong thập niên 80).
Một số điều có thể ảnh hưởng đến hoạt động của trình biên dịch hoặc trình liên kết nhưng không được chỉ định trong cú pháp của C hoặc C ++:
- giải quyết phụ thuộc
- yêu cầu thư viện bên ngoài (bao gồm cả thứ tự phụ thuộc)
- mức độ tối ưu hóa
- cài đặt cảnh báo
- phiên bản đặc tả ngôn ngữ
- ánh xạ liên kết (phần nào đi đâu trong chương trình cuối cùng)
- kiến trúc mục tiêu
Một số trong số này có thể được phát hiện, nhưng chúng không thể được chỉ định; ví dụ: tôi có thể phát hiện C ++ nào đang được sử dụng __cplusplus
, nhưng tôi không thể chỉ định rằng C ++ 98 là mã được sử dụng cho mã của tôi trong chính mã; Tôi phải chuyển nó dưới dạng cờ cho trình biên dịch trong Makefile hoặc tạo một cài đặt trong hộp thoại.
Mặc dù bạn có thể nghĩ rằng hệ thống "độ phân giải phụ thuộc" tồn tại trong trình biên dịch, tự động tạo các bản ghi phụ thuộc, các bản ghi này chỉ cho biết tệp tiêu đề nào mà tệp nguồn đã cho sử dụng. Chúng không thể chỉ ra những mô-đun mã nguồn bổ sung nào được yêu cầu để liên kết vào một chương trình thực thi, bởi vì không có cách tiêu chuẩn nào trong C hoặc C ++ để chỉ ra rằng một tệp tiêu đề đã cho là định nghĩa giao diện cho một mô-đun mã nguồn khác chứ không phải chỉ là một bó các dòng bạn muốn hiển thị ở nhiều nơi để bạn không lặp lại chính mình. Có những truyền thống trong các quy ước đặt tên tệp, nhưng chúng không được biết đến hoặc được thực thi bởi trình biên dịch và trình liên kết.
Một vài trong số này có thể được thiết lập bằng cách sử dụng #pragma
, nhưng điều này là không chuẩn, và tôi đã nói về tiêu chuẩn. Tất cả những điều này có thể được chỉ định bởi một tiêu chuẩn, nhưng không có lợi cho khả năng tương thích ngược. Sự khôn ngoan phổ biến là makefiles và IDE không bị hỏng, vì vậy đừng sửa chúng.
Python xử lý tất cả điều này trong ngôn ngữ. Ví dụ, import
chỉ định một phụ thuộc mô-đun rõ ràng, ngụ ý cây phụ thuộc và các mô-đun không được chia thành các tệp tiêu đề và nguồn (tức là giao diện và triển khai).