Bìa Hướng dẫn chính thức về phong cách mã nguồn của ngôn ngữ lập trình Python
- Bố cục mã nguồn
- Độ dài dòng tối đa
- Nơi phá vỡ toán tử nhị phân
- Dòng trống
- Nhập (import)
- Khoảng trắng trong biểu thức và câu lệnh
- Các khoảng trắng khác
- Bình luận (comments)
- Đặt tên
- Các quy tắc khác
Lần đầu tiên tôi biết đến PEP8 là khi nhận được thông báo định dạng từ PyCharm. Lúc đó, tôi mới bắt đầu học Python và chỉ biết rằng Python sử dụng mức độ thụt dòng nghiêm ngặt để kiểm soát cấu trúc. Tôi chỉ làm theo từng bước gõ mã mà thầy hướng dẫn. Tôi tiếp xúc với Python qua cuốn sách “Từ cơ bản đến thành thạo Python”. Trong những Nohu31 Win bài học đầu tiên, giáo viên là một nữ giảng viên. Cô ấy dạy cách gõ mã trên IDLE, nhưng mã của cô luôn rất gọn gàng, dù là gõ tay hoàn toàn. Điều này bởi vì cô tuân thủ một trong các quy tắc của PEP8 - bình luận “#” nên cách hai khoảng trống sau ký tự cuối cùng của dòng mã, và nội dung bình luận cách “#” một khoảng trống, ví dụ a = 1 # Bình luận xxx
. Tính dễ đọc của mã nguồn không cần phải bàn cãi, nhưng mỗi người có tiêu chuẩn khác nhau về sự gọn gàng của mã. Vì vậy, Kenneth Reitz đã tổng hợp một bộ quy tắc viết mã Python. Bộ quy tắc này hiện nay được cộng đồng chấp nhận rộng rãi và được học hỏi nhiều. Website chính thức của PEP8 là pep8.org, bài viết này sẽ chọn lọc và chia sẻ một số quy tắc thường dùng từ trang web này.
Thụt dòng
Mỗi cấp độ thụt dòng sử dụng bốn khoảng trống. Các dòng liên tiếp nên sử dụng nối dòng ngầm trong dấu ngoặc tròn, vuông hoặc móc của Python hoặc sử dụng thụt dòng treo. Khi sử dụng thụt dòng treo, các phần tử được gói cần cân nhắc điều sau: dòng đầu tiên không nên có bất kỳ tham số nào và nên thụt thêm để rõ ràng phân biệt đây là dòng tiếp tục. Khi danh sách tham số của hàm quá dài và cần chuyển sang dòng mới, các tham số ở dòng mới nên giữ thẳng hàng với các tham số ở dòng trước. Nếu chọn chuyển dòng trước tham số đầu tiên, tham số đầu tiên nên thụt hai cấp độ để phân biệt với dòng mã tiếp theo. Đúng:
|
|
Sai:
|
|
Có thể sử dụng ít hơn bốn khoảng trống cho thụt dòng. Tùy chọn:
|
|
Khi phần điều kiện của if-đề cập đủ dài và cần viết trên nhiều dòng, cần lưu ý rằng hai ký tự khóa (ví dụ if), cộng một khoảng trống, cộng dấu ngoặc mở, tạo ra thụt tự nhiên bốn khoảng trống cho các dòng tiếp theo của điều kiện. Điều này có thể gây xung đột thị giác với mã khối lồng trong if-statement, vốn cũng thụt bốn khoảng trống. PEP này không quy định cụ thể cách (hoặc liệu có hay không) phân biệt trực quan giữa các dòng điều kiện và khối lồng bên trong if-statement. Các tùy chọn chấp nhận được bao gồm nhưng không giới hạn:
|
|
Trong cấu trúc nhiều dòng, dấu ngoặc/móc/vuông phải đối齐 dưới ký tự không trắng đầu tiên của dòng cuối cùng trong danh sách, ví dụ:
|
|
Hoặc nó có thể xếp dưới ký tự đầu tiên của dòng bắt đầu cấu trúc nhiều dòng, ví dụ:
|
|
Chọn khoảng trắng hay tab
Khoảng trắng là phương pháp thụt dòng ưu tiên. Python 3 không cho phép trộn tab và khoảng trắng trong thụt dòng.
Độ dài dòng tối đa
Giới hạn tất cả các dòng tối đa 79 ký tự. Đối với khối văn bản dài có ít hạn chế cấu trúc (chuỗi tài liệu hoặc bình luận), độ dài dòng nên giới hạn ở 72 ký tự. Việc giới hạn chiều rộng cửa sổ biên tập giúp mở nhiều tệp cùng lúc và hoạt động tốt khi sử dụng công cụ đánh giá mã hiển thị hai phiên bản trong các cột kề nhau. Phần lớn các công cụ mặc định gói đoạn mã sẽ phá hủy cấu trúc trực quan của mã, khiến nó khó hiểu hơn. Các giới hạn này được chọn để tránh việc tự động xuống dòng trong cửa sổ biên tập có chiều rộng 80 ký tự, ngay cả khi công cụ đặt dấu hiệu ở cột cuối cùng. Một số công cụ dựa trên web có thể không cung cấp xuống dòng động. Một số đội nhóm thích độ dài dòng dài hơn. Đối với mã được duy trì riêng lẻ hoặc chủ yếu bởi các đội nhóm có thể thống nhất vấn đề này, có thể tăng độ dài dòng danh nghĩa từ 80 lên 100 ký tự (tăng hiệu quả độ dài tối đa lên 99 ký tự), miễn là bình luận và chuỗi tài liệu vẫn gói ở 72 ký tự. Phương pháp xuống dòng ưu tiên là sử dụng nối dòng ngầm của Python trong dấu ngoặc/móc/vuông. Bằng cách đặt biểu thức trong dấu ngoặc, bạn có thể chia nhỏ dòng dài thành nhiều dòng. Những phương pháp này nên được ưu tiên hơn việc sử dụng dấu ngược để tiếp dòng. Dấu ngược đôi khi vẫn có thể phù hợp. Ví dụ, các câu lệnh with dài không thể sử dụng nối dòng ngầm, nên dấu ngược là chấp nhận được:
|
|
Nơi phá vỡ toán tử nhị phân
Trong mã Python, được phép phá vỡ trước hoặc sau toán tử nhị phân, miễn là tuân thủ quy ước nhất quán tại địa phương. Đối với mã mới, nên tuân theo phong cách Knuth, tức là phá vỡ trước toán tử.
|
|
Dòng trống
Bao quanh định nghĩa hàm và lớp hàng đầu bằng hai dòng trống. Định nghĩa phương thức trong lớp được bao quanh bởi một dòng trống. Các dòng trống bổ sung có thể được sử dụng (có tiết chế) để phân tách nhóm hàm liên quan. Có thể bỏ qua dòng trống giữa các dòng mã đơn ngắn liên quan (ví dụ một loạt thực hiện giả). Trong hàm, cố gắng sử dụng ít dòng trống để biểu thị phần logic.
Nhập (import)
Nếu có nhiều nhập thì nên nhập từng dòng. Đúng:
|
|
Sai:
|
|
Nhưng nhập có giới hạn có thể đặt trên cùng một dòng. Đúng:
|
|
Nhập luôn được đặt ở đầu tệp, ngay sau tất cả chú thích mô đun và chuỗi tài liệu, trước các giá trị và hằng số toàn cầu của mô đun. Nhập nên được phân nhóm theo thứ tự sau:
- Nhập thư viện chuẩn
- Nhập từ các bên thứ ba liên quan
- Nhập cụ thể ứng dụng/thư viện cục bộ
Bạn nên đặt một dòng trống giữa mỗi nhóm nhập. Ưu tiên sử dụng nhập tuyệt đối, vì chúng làm cho biến có tính khả đọc cao hơn và có ít cảnh báo lỗi hơn.
|
|
Nếu nhập tuyệt đối quá rườm rà, có thể sử dụng nhập tương đối rõ ràng.
|
|
Mã thư viện chuẩn nên tránh bố cục gói phức tạp và luôn sử dụng nhập tuyệt đối. Không bao giờ nên sử dụng nhập tương đối ẩn và đã bị loại bỏ trong Python 3. Khi nhập lớp từ mô đun chứa lớp, thường có thể viết như sau:
|
|
Nếu các nhập trên gây xung đột tên, có thể sử dụng kiểu nhập sau:
|
|
Rồi sử dụng myclass.MyClass
và foo.bar.yourclass.YourClass
.
Nên tránh sử dụng nhập bằng dấu hoa thị (from … import *), vì chúng làm cho tên xuất hiện trong không gian tên trở nên không rõ ràng, gây nhầm lẫn cho độc giả và nhiều công cụ tự động hóa. Nhập bằng dấu hoa thị có một trường hợp biện minh, là tái xuất bản giao diện nội bộ dưới dạng một phần của API công khai (ví dụ, sử dụng định nghĩa từ mô đun gia tốc tùy chọn để ghi đè định nghĩa thực thi thuần Python của giao diện, và không biết trước định nghĩa nào sẽ bị ghi đè).
Khoảng trắng trong biểu thức và câu lệnh
Tránh các khoảng trắng thừa trong các trường hợp sau: Ngay trong dấu ngoặc/móc/móc: Đúng:
|
|
Sai:
|
|
Giữa dấu phẩy và dấu ngoặc đóng phía sau: Đúng:
|
|
Sai:
|
|
Ngay trước dấu phẩy, dấu chấm phẩy hoặc dấu hai chấm: Đúng:
|
|
Sai:
|
|
Tuy nhiên, trong cắt lát, dấu hai chấm hoạt động giống như một toán tử nhị phân và nên có số lượng khoảng trắng bằng nhau ở cả hai bên (xem xét nó như một toán tử có ưu tiên thấp nhất). Trong cắt lát mở rộng, hai dấu hai chấm phải áp dụng cùng khoảng cách. Ngoại lệ: khi bỏ qua tham số cắt lát, khoảng trắng sẽ bị bỏ qua. Đúng:
|
|
Sai:
|
|
Ngay trước dấu ngoặc mở bắt đầu danh sách tham số gọi hàm: Đúng:
|
|
Sai:
|
|
Ngay trước dấu ngoặc mở bắt đầu chỉ mục hoặc cắt lát: Sai:
|
|
Sai:
|
|
Có nhiều khoảng trắng xung quanh toán tử gán (hoặc khác) để căn chỉnh với toán tử khác. Đúng:
|
|
Sai:
|
|
Luôn sử dụng một khoảng trắng duy nhất ở cả hai bên của các toán tử nhị phân sau: gán (=), gán tăng cường (+=, -=,…), so sánh (==, <, >, !=, <=, >=, in, not in, is, is not), và boolean (and, or, not). Đúng:
|
|
Sai:
|
|
Khi sử dụng các toán tử có độ ưu tiên khác nhau, hãy cân nhắc thêm khoảng trắng xung quanh toán tử có độ ưu tiên thấp nhất. Hãy sử dụng sự phán đoán của bạn; nhưng đừng bao giờ sử dụng nhiều hơn một khoảng trắng và luôn luôn sử dụng cùng số lượng khoảng trắng ở cả hai bên của toán tử nhị phân. Đúng:
|
|
Sai:
|
|
Khi sử dụng dấu bằng để chỉ định tham số khóa hoặc giá trị mặc định, đừng thêm khoảng trắng xung quanh dấu bằng. Đúng:
|
|
Sai:
|
|
Bình luận hàm nên sử dụng quy tắc thông thường của dấu hai chấm và luôn có khoảng trắng xung quanh mũi tên “->” (nếu có). Đúng:
|
|
Sai:
|
|
Khi kết hợp bình luận tham số với giá trị mặc định, sử dụng khoảng trắng xung quanh dấu bằng (nhưng chỉ áp dụng cho các tham số có cả bình luận và giá trị mặc định). Đúng:
|
|
Sai:
|
|
Câu lệnh hợp thành (nhiều câu lệnh trên cùng một dòng) thường không được khuyến khích. Đúng:
|
|
Sai:
|
|
Bình luận
Bình luận nội tuyến là bình luận nằm cùng dòng với câu lệnh. Bình luận nội tuyến nên cách câu lệnh ít nhất hai khoảng trống. Chúng nên bắt đầu bằng dấu # và một khoảng trống. Bình luận nội tuyến thường không cần thiết, thực tế nếu chúng chỉ nói lên điều hiển nhiên thì sẽ làm mất tập trung. Việc này không có ý nghĩa gì:
|
|
Bình luận nên sử dụng chuỗi tài liệu nhiều hơn. Để biết thêm về chuỗi tài liệu, vui lòng đọc bài viết dưới đây. {cat_insidepost id=“216”}
Đặt tên
Quy tắc đặt tên
Có một số cách đặt tên phổ biến:
- b (chữ cái nhỏ đơn)
- B (chữ cái lớn đơn)
- lowercase (từ tiếng Anh viết thường)
- lower_case_with_underscores (từ viết thường với gạch dưới)
- UPPERCASE (toàn bộ chữ in hoa)
- UPPER_CASE_WITH_UNDERSCORES (viết hoa với gạch dưới)
- CapitalizedWords (hoặc CapWords, CamelCase, StudlyCaps) (phong cách lạc đà)
- mixedCase (khác với CapitalizedWords)
- Capitalized_Words_With_Underscores (phong cách hề)
Khi sử dụng略