Python là ngôn ngữ động chính được sử dụng tại Google. Hướng dẫn về phong cách này là danh sách những điều nên làm và không nên làm đối với các chương trình Python
Để giúp bạn định dạng mã chính xác, chúng tôi đã tạo tệp cài đặt cho Vim. Đối với Emacs, cài đặt mặc định sẽ ổn
Nhiều nhóm sử dụng trình định dạng tự động yapf để tránh tranh cãi về định dạng
2 Quy tắc ngôn ngữ Python
2. 1 xơ vải
Chạy
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 trên mã của bạn bằng cách sử dụng pylintrc này2. 1. 1 Định nghĩa
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 là một công cụ để tìm lỗi và các vấn đề về kiểu dáng trong mã nguồn Python. Nó tìm thấy các vấn đề thường được trình biên dịch bắt gặp đối với các ngôn ngữ kém năng động hơn như C và C++. Do tính chất động của Python, một số cảnh báo có thể không chính xác; 2. 1. 2 Ưu điểm
Bắt các lỗi dễ bỏ sót như lỗi chính tả, sử dụng-vars-trước khi gán, v.v.
2. 1. 3 nhược điểm
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 không hoàn hảo. Để tận dụng lợi thế của nó, đôi khi chúng ta cần phải viết xung quanh nó, loại bỏ các cảnh báo của nó hoặc sửa chữa nó2. 1. 4 Quyết định
Hãy chắc chắn rằng bạn chạy
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 trên mã của bạnLoại bỏ các cảnh báo nếu chúng không phù hợp để các vấn đề khác không bị ẩn. Để chặn cảnh báo, bạn có thể đặt nhận xét cấp dòng
dict = 'something awful' # Bad Idea.. pylint: disable=redefined-builtin
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 cảnh báo, mỗi cảnh báo được xác định bằng tên tượng trưng [def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
23] Cảnh báo dành riêng cho Google bắt đầu bằng def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
24Nếu lý do ngăn chặn không rõ ràng từ tên biểu tượng, hãy thêm một lời giải thích
Loại bỏ theo cách này có lợi thế là chúng ta có thể dễ dàng tìm kiếm các loại bỏ và xem lại chúng
Bạn có thể nhận danh sách
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 cảnh báo bằng cách thực hiệnĐể có thêm thông tin về một tin nhắn cụ thể, hãy sử dụng
Thích
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
26 hơn mẫu cũ hơn không dùng nữa def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
27Có thể loại bỏ các cảnh báo đối số không sử dụng bằng cách xóa các biến ở đầu hàm. Luôn bao gồm một bình luận giải thích lý do tại sao bạn xóa nó. “Không sử dụng. " là đủ. Ví dụ
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
Các hình thức phổ biến khác để loại bỏ cảnh báo này bao gồm sử dụng '
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
28' làm mã định danh cho đối số không được sử dụng hoặc thêm tiền tố vào tên đối số bằng 'def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
29' hoặc gán chúng cho 'def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
28'. Các hình thức này được cho phép nhưng không còn được khuyến khích. Những trình gọi ngắt này chuyển đối số theo tên và không thực thi rằng đối số thực sự không được sử dụng2. 2 nhập khẩu
Chỉ sử dụng các câu lệnh
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
31 cho các gói và mô-đun, không dùng cho các lớp hoặc chức năng riêng lẻ2. 2. 1 Định nghĩa
Cơ chế tái sử dụng để chia sẻ mã từ mô-đun này sang mô-đun khác
2. 2. 2 Ưu điểm
Quy ước quản lý không gian tên rất đơn giản. Nguồn của mỗi mã định danh được chỉ định một cách nhất quán;
2. 2. 3 nhược điểm
Tên mô-đun vẫn có thể xung đột. Một số tên mô-đun dài bất tiện
2. 2. 4 Quyết định
- Sử dụng
35 để nhập các gói và mô-đundef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
- Sử dụng
36 trong đódef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
34 là tiền tố gói vàdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
38 là tên mô-đun không có tiền tốdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
- Sử dụng
39 nếu hai mô-đun có têndef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
38 được nhập, nếudef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
38 xung đột với tên cấp cao nhất được xác định trong mô-đun hiện tại hoặc nếudef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
38 là một tên dài bất tiệndef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
- Chỉ sử dụng
43 khidef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
44 là cách viết tắt tiêu chuẩn [e. g. ,def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
45 chodef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
46]def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Ví dụ: mô-đun
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
47 có thể được nhập như saufrom sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
Không sử dụng tên họ hàng trong nhập khẩu. Ngay cả khi mô-đun nằm trong cùng một gói, hãy sử dụng tên gói đầy đủ. Điều này giúp ngăn việc vô tình nhập một gói hai lần
2. 2. 4. 1 miễn trừMiễn trừ từ quy tắc này
- Các ký hiệu từ các mô-đun sau được sử dụng để hỗ trợ phân tích tĩnh và kiểm tra kiểu
- Chuyển hướng từ
2. 3 gói
Nhập từng mô-đun bằng vị trí tên đường dẫn đầy đủ của mô-đun
2. 3. 1 Ưu điểm
Tránh xung đột về tên mô-đun hoặc nhập sai do đường dẫn tìm kiếm mô-đun không như tác giả mong đợi. Giúp tìm kiếm các mô-đun dễ dàng hơn
2. 3. 2 nhược điểm
Làm cho việc triển khai mã trở nên khó khăn hơn vì bạn phải sao chép hệ thống phân cấp gói. Không thực sự là một vấn đề với các cơ chế triển khai hiện đại
2. 3. 3 Quyết định
Tất cả mã mới phải nhập từng mô-đun theo tên gói đầy đủ của nó
Nhập khẩu phải như sau
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
[giả sử tệp này tồn tại ở
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
48 nơi mà def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
49 cũng tồn tại]No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
Thư mục chứa tệp nhị phân chính không nên được coi là ở trong
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
50 mặc dù điều đó xảy ra trong một số môi trường. Trong trường hợp này, mã phải giả định rằng def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
51 đề cập đến bên thứ ba hoặc gói cấp cao nhất có tên là def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
52, không phải là địa phương def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
492. 4 ngoại lệ
Ngoại lệ được cho phép nhưng phải được sử dụng cẩn thận
2. 4. 1 Định nghĩa
Ngoại lệ là phương tiện thoát ra khỏi luồng điều khiển thông thường để xử lý lỗi hoặc các điều kiện ngoại lệ khác
2. 4. 2 Ưu điểm
Luồng điều khiển của mã hoạt động bình thường không bị lộn xộn bởi mã xử lý lỗi. Nó cũng cho phép luồng điều khiển bỏ qua nhiều khung khi một điều kiện nhất định xảy ra, e. g. , quay lại từ N hàm lồng nhau trong một bước thay vì phải tìm mã lỗi thông qua
2. 4. 3 nhược điểm
Có thể khiến luồng điều khiển bị nhầm lẫn. Dễ bỏ sót các trường hợp lỗi khi gọi thư viện
2. 4. 4 Quyết định
Ngoại lệ phải tuân theo các điều kiện nhất định
Sử dụng các lớp ngoại lệ tích hợp khi nó hợp lý. Ví dụ: tăng số
54 để chỉ ra lỗi lập trình như điều kiện tiên quyết bị vi phạm [chẳng hạn như nếu bạn được cho số âm nhưng yêu cầu số dương]. Không sử dụng câu lệnhdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
55 để xác thực giá trị đối số của API công khai.def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
55 được sử dụng để đảm bảo tính đúng đắn bên trong, không phải để bắt buộc sử dụng đúng cách cũng như không chỉ ra rằng một số sự kiện bất ngờ đã xảy ra. Nếu một ngoại lệ được mong muốn trong các trường hợp sau, hãy sử dụng câu lệnh nâng cao. Ví dụdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Yes: def connect_to_next_port[self, minimum: int] -> int: """Connects to the next available port. Args: minimum: A port value greater or equal to 1024. Returns: The new minimum port. Raises: ConnectionError: If no available port is found. """ if minimum < 1024: # Note that this raising of ValueError is not mentioned in the doc # string's "Raises:" section because it is not appropriate to # guarantee this specific behavioral reaction to API misuse. raise ValueError[f'Min. port must be at least 1024, not {minimum}.'] port = self._find_next_open_port[minimum] if port is None: raise ConnectionError[ f'Could not connect to service on port {minimum} or higher.'] assert port >= minimum, [ f'Unexpected port {port} when minimum was {minimum}.'] return port
No: def connect_to_next_port[self, minimum: int] -> int: """Connects to the next available port. Args: minimum: A port value greater or equal to 1024. Returns: The new minimum port. """ assert minimum >= 1024, 'Minimum port must be at least 1024.' port = self._find_next_open_port[minimum] assert port is not None return port
Thư viện hoặc gói có thể xác định ngoại lệ của riêng họ. Khi làm như vậy, họ phải kế thừa từ một lớp ngoại lệ hiện có. Tên ngoại lệ phải kết thúc bằng
57 và không nên lặp lại [def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
58]def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Không bao giờ sử dụng câu lệnh bắt tất cả
59 hoặc bắtdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
60 hoặcdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
61, trừ khi bạndef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
- tăng lại ngoại lệ, hoặc
- tạo một điểm cách ly trong chương trình nơi các ngoại lệ không được lan truyền mà thay vào đó được ghi lại và loại bỏ, chẳng hạn như bảo vệ một chuỗi khỏi sự cố bằng cách bảo vệ khối ngoài cùng của nó
Python rất khoan dung về vấn đề này và
59 sẽ thực sự nắm bắt mọi thứ kể cả tên sai chính tả, sys. các cuộc gọi exit[], Ctrl+C ngắt, lỗi nhỏ nhất và tất cả các loại ngoại lệ khác mà bạn đơn giản là không muốn nắm bắtdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Giảm thiểu số lượng mã trong một khối
63/def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
64. Phần thân củadef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
63 càng lớn thì càng có nhiều khả năng một ngoại lệ sẽ được đưa ra bởi một dòng mã mà bạn không mong đợi sẽ đưa ra một ngoại lệ. Trong những trường hợp đó, khốidef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
63/def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
64 ẩn một lỗi thực sựdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Sử dụng mệnh đề
68 để thực thi mã cho dù có hay không một ngoại lệ được đưa ra trong khốidef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
63. Điều này thường hữu ích cho việc dọn dẹp, tôi. e. , đóng một tập tindef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
2. 5 trạng thái toàn cầu có thể thay đổi
Tránh trạng thái toàn cầu có thể thay đổi
2. 5. 1 Định nghĩa
Các giá trị cấp mô-đun hoặc thuộc tính lớp có thể bị thay đổi trong quá trình thực thi chương trình
2. 5. 2 Ưu điểm
Thỉnh thoảng hữu ích
2. 5. 3 nhược điểm
Phá vỡ đóng gói. Thiết kế như vậy có thể gây khó khăn cho việc đạt được các mục tiêu hợp lệ. Ví dụ: nếu trạng thái chung được sử dụng để quản lý kết nối cơ sở dữ liệu, thì việc kết nối với hai cơ sở dữ liệu khác nhau cùng một lúc [chẳng hạn như đối với sự khác biệt về tính toán trong quá trình di chuyển] sẽ trở nên khó khăn. Các vấn đề tương tự dễ dàng phát sinh với các cơ quan đăng ký toàn cầu
Có khả năng thay đổi hành vi của mô-đun trong quá trình nhập, vì việc gán cho các biến toàn cục được thực hiện khi mô-đun được nhập lần đầu
2. 5. 4 Quyết định
Tránh trạng thái toàn cầu có thể thay đổi
Trong những trường hợp hiếm hoi khi sử dụng trạng thái toàn cầu được đảm bảo, các thực thể toàn cầu có thể thay đổi phải được khai báo ở cấp độ mô-đun hoặc dưới dạng thuộc tính lớp và được tạo nội bộ bằng cách thêm một _______28 vào tên. Nếu cần, quyền truy cập bên ngoài vào trạng thái toàn cầu có thể thay đổi phải được thực hiện thông qua các hàm công khai hoặc phương thức lớp. Xem bên dưới. Vui lòng giải thích lý do thiết kế tại sao trạng thái chung có thể thay đổi đang được sử dụng trong nhận xét hoặc tài liệu được liên kết từ nhận xét
Hằng số cấp mô-đun được cho phép và khuyến khích. Ví dụ.
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
71 cho hằng số sử dụng nội bộ hoặc def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
72 cho hằng số API công khai. Các hằng số phải được đặt tên bằng cách sử dụng tất cả các chữ hoa có dấu gạch dưới. Xem bên dưới2. 6 Các lớp và hàm lồng nhau/cục bộ/bên trong
Các hàm hoặc lớp cục bộ lồng nhau vẫn ổn khi được sử dụng để đóng trên một biến cục bộ. Các lớp bên trong vẫn ổn
2. 6. 1 Định nghĩa
Một lớp có thể được định nghĩa bên trong một phương thức, hàm hoặc lớp. Một hàm có thể được định nghĩa bên trong một phương thức hoặc hàm. Các hàm lồng nhau có quyền truy cập chỉ đọc vào các biến được xác định trong phạm vi kèm theo
2. 6. 2 Ưu điểm
Cho phép định nghĩa các lớp và chức năng tiện ích chỉ được sử dụng bên trong phạm vi rất hạn chế. Rất ADT-y. Thường được sử dụng để thực hiện trang trí
2. 6. 3 nhược điểm
Các hàm và lớp lồng nhau không thể được kiểm tra trực tiếp. Việc lồng nhau có thể làm cho chức năng bên ngoài dài hơn và khó đọc hơn
2. 6. 4 Quyết định
Họ ổn với một số lưu ý. Tránh các hàm hoặc lớp lồng nhau trừ khi đóng trên một giá trị cục bộ khác với
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
73 hoặc def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
74. Không lồng chức năng chỉ để ẩn nó khỏi người dùng mô-đun. Thay vào đó, hãy đặt tiền tố tên của nó bằng _ ở cấp độ mô-đun để nó vẫn có thể được truy cập bằng các thử nghiệm2. 7 cách hiểu và biểu thức trình tạo
Được rồi để sử dụng cho các trường hợp đơn giản
2. 7. 1 Định nghĩa
Khả năng hiểu List, Dict và Set cũng như các biểu thức trình tạo cung cấp một cách ngắn gọn và hiệu quả để tạo các loại bộ chứa và bộ lặp mà không cần sử dụng các vòng lặp truyền thống,
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
75, def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
76 hoặc def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
772. 7. 2 Ưu điểm
Việc hiểu đơn giản có thể rõ ràng và đơn giản hơn các kỹ thuật tạo chính tả, danh sách hoặc tập hợp khác. Biểu thức trình tạo có thể rất hiệu quả, vì chúng tránh hoàn toàn việc tạo danh sách
2. 7. 3 nhược điểm
Có thể khó đọc các biểu thức trình tạo hoặc hiểu phức tạp
2. 7. 4 Quyết định
Được rồi để sử dụng cho các trường hợp đơn giản. Mỗi phần phải vừa trên một dòng. biểu thức ánh xạ, mệnh đề
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
78, biểu thức bộ lọc. Nhiều mệnh đề def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
78 hoặc biểu thức bộ lọc không được phép. Thay vào đó, hãy sử dụng các vòng lặp khi mọi thứ trở nên phức tạp hơnYes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
2. 8 Iterator và Operator mặc định
Sử dụng các trình lặp và toán tử mặc định cho các loại hỗ trợ chúng, như danh sách, từ điển và tệp
2. 8. 1 Định nghĩa
Các loại vùng chứa, như từ điển và danh sách, xác định các trình vòng lặp mặc định và toán tử kiểm tra tư cách thành viên [“in” và “not in”]
2. 8. 2 Ưu điểm
Các trình vòng lặp và toán tử mặc định rất đơn giản và hiệu quả. Chúng thể hiện thao tác trực tiếp mà không cần gọi thêm phương thức. Một hàm sử dụng các toán tử mặc định là chung chung. Nó có thể được sử dụng với bất kỳ loại nào hỗ trợ hoạt động
2. 8. 3 nhược điểm
Bạn không thể biết loại đối tượng bằng cách đọc tên phương thức [trừ khi biến có chú thích loại]. Đây cũng là một lợi thế
2. 8. 4 Quyết định
Sử dụng các trình lặp và toán tử mặc định cho các loại hỗ trợ chúng, như danh sách, từ điển và tệp. Các loại tích hợp cũng xác định các phương thức lặp. Ưu tiên các phương thức này hơn các phương thức trả về danh sách, ngoại trừ việc bạn không nên thay đổi vùng chứa trong khi lặp lại nó
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
0def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
12. 9 máy phát điện
Sử dụng máy phát điện khi cần thiết
2. 9. 1 Định nghĩa
Hàm tạo trả về một trình vòng lặp mang lại một giá trị mỗi khi nó thực thi câu lệnh năng suất. Sau khi nó mang lại một giá trị, trạng thái thời gian chạy của hàm tạo bị tạm dừng cho đến khi cần giá trị tiếp theo
2. 9. 2 Ưu điểm
Mã đơn giản hơn, vì trạng thái của các biến cục bộ và luồng điều khiển được giữ nguyên cho mỗi cuộc gọi. Trình tạo sử dụng ít bộ nhớ hơn so với hàm tạo toàn bộ danh sách giá trị cùng một lúc
2. 9. 3 nhược điểm
Các biến cục bộ trong trình tạo sẽ không được thu gom rác cho đến khi trình tạo bị tiêu thụ đến mức cạn kiệt hoặc chính nó đã được thu gom rác
2. 9. 4 Quyết định
Khỏe. Sử dụng “Năng suất. ” thay vì “Trả về. ” trong chuỗi tài liệu cho các hàm tạo
Nếu trình tạo quản lý một tài nguyên đắt tiền, hãy đảm bảo buộc dọn dẹp
Một cách hay để dọn dẹp là bọc trình tạo bằng trình quản lý ngữ cảnh PEP-0533
2. 10 Hàm Lambda
Được rồi cho một lớp lót. Thích các biểu thức trình tạo hơn
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
75 hoặc def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
76 với một def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
772. 10. 1 Định nghĩa
Lambdas định nghĩa các hàm ẩn danh trong một biểu thức, trái ngược với một câu lệnh
2. 10. 2 Ưu điểm
Tiện lợi
2. 10. 3 nhược điểm
Khó đọc và gỡ lỗi hơn các chức năng cục bộ. Việc thiếu tên có nghĩa là dấu vết ngăn xếp khó hiểu hơn. Tính biểu cảm bị hạn chế vì chức năng chỉ có thể chứa một biểu thức
2. 10. 4 Quyết định
Được rồi để sử dụng chúng cho một lớp lót. Nếu mã bên trong hàm lambda dài hơn 60-80 ký tự, thì có lẽ tốt hơn nên xác định mã đó là mã thông thường
Đối với các hoạt động phổ biến như phép nhân, hãy sử dụng các hàm từ mô-đun
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
83 thay vì các hàm lambda. Ví dụ: thích def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
84 hơn là def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
852. 11 Biểu thức điều kiện
Được rồi cho các trường hợp đơn giản
2. 11. 1 Định nghĩa
Biểu thức điều kiện [đôi khi được gọi là “toán tử bậc ba”] là cơ chế cung cấp cú pháp ngắn hơn cho câu lệnh if. Ví dụ.
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
862. 11. 2 Ưu điểm
Ngắn gọn và thuận tiện hơn câu lệnh if
2. 11. 3 nhược điểm
Có thể khó đọc hơn câu lệnh if. Điều kiện có thể khó xác định nếu biểu thức dài
2. 11. 4 Quyết định
Được rồi để sử dụng cho các trường hợp đơn giản. Mỗi phần phải vừa trên một dòng. biểu thức đúng, biểu thức if, biểu thức khác. Sử dụng câu lệnh if hoàn chỉnh khi mọi thứ trở nên phức tạp hơn
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
2def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
32. 12 giá trị đối số mặc định
Được rồi trong hầu hết các trường hợp
2. 12. 1 Định nghĩa
Bạn có thể chỉ định giá trị cho các biến ở cuối danh sách tham số của hàm, chẳng hạn như. g. ,
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
87. Nếu def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
88 được gọi chỉ với một đối số, thì def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
89 được đặt thành 0. Nếu nó được gọi với hai đối số, thì def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
89 có giá trị của đối số thứ hai2. 12. 2 Ưu điểm
Thường thì bạn có một hàm sử dụng nhiều giá trị mặc định, nhưng trong một số trường hợp hiếm hoi, bạn muốn ghi đè lên các giá trị mặc định. Các giá trị đối số mặc định cung cấp một cách dễ dàng để thực hiện việc này mà không cần phải xác định nhiều hàm cho các trường hợp ngoại lệ hiếm gặp. Vì Python không hỗ trợ các phương thức/hàm quá tải, nên các đối số mặc định là một cách dễ dàng để “làm giả” hành vi quá tải
2. 12. 3 nhược điểm
Các đối số mặc định được đánh giá một lần tại thời điểm tải mô-đun. Điều này có thể gây ra sự cố nếu đối số là đối tượng có thể thay đổi, chẳng hạn như danh sách hoặc từ điển. Nếu chức năng sửa đổi đối tượng [e. g. , bằng cách thêm một mục vào danh sách], giá trị mặc định được sửa đổi
2. 12. 4 Quyết định
Được rồi để sử dụng với cảnh báo sau
Không sử dụng các đối tượng có thể thay đổi làm giá trị mặc định trong định nghĩa hàm hoặc phương thức
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
4def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
52. 13 thuộc tính
Các thuộc tính có thể được sử dụng để kiểm soát việc nhận hoặc thiết lập các thuộc tính yêu cầu tính toán hoặc logic thông thường. Việc triển khai thuộc tính phải phù hợp với kỳ vọng chung của quyền truy cập thuộc tính thông thường. rằng chúng rẻ, đơn giản và không gây ngạc nhiên
2. 13. 1 Định nghĩa
Một cách để gói các cuộc gọi phương thức để nhận và đặt thuộc tính làm quyền truy cập thuộc tính tiêu chuẩn
2. 13. 2 Ưu điểm
- Cho phép API gán và truy cập thuộc tính thay vì gọi phương thức
- Có thể được sử dụng để tạo thuộc tính chỉ đọc
- Cho phép tính toán lười biếng
- Cung cấp một cách để duy trì giao diện chung của một lớp khi các phần bên trong phát triển độc lập với người dùng lớp
2. 13. 3 nhược điểm
- Có thể ẩn các tác dụng phụ giống như quá tải toán tử
- Có thể gây nhầm lẫn cho các lớp con
2. 13. 4 Quyết định
Các thuộc tính được cho phép, nhưng, giống như quá tải toán tử, chỉ nên được sử dụng khi cần thiết và phù hợp với mong đợi của truy cập thuộc tính điển hình;
Ví dụ: không được phép sử dụng thuộc tính để vừa lấy vừa đặt thuộc tính nội bộ. không có tính toán xảy ra, vì vậy thuộc tính là không cần thiết []. Trong khi đó, việc sử dụng một thuộc tính để kiểm soát quyền truy cập thuộc tính hoặc để tính toán một giá trị có nguồn gốc tầm thường được cho phép. logic rất đơn giản và không có gì đáng ngạc nhiên
Các thuộc tính nên được tạo bằng
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
91. Thực hiện thủ công một bộ mô tả thuộc tính được coi là mộtKế thừa với các thuộc tính có thể không rõ ràng. Không sử dụng các thuộc tính để thực hiện tính toán mà một lớp con có thể muốn ghi đè và mở rộng
2. 14 Đánh giá Đúng/Sai
Sử dụng sai "ngầm" nếu có thể
2. 14. 1 Định nghĩa
Python đánh giá các giá trị nhất định là
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
92 khi ở trong ngữ cảnh boolean. Một "quy tắc ngón tay cái" nhanh là tất cả các giá trị "trống rỗng" đều được coi là sai, vì vậy, ________93 tất cả đều được đánh giá là sai trong ngữ cảnh boolean2. 14. 2 Ưu điểm
Các điều kiện sử dụng booleans Python dễ đọc hơn và ít bị lỗi hơn. Trong hầu hết các trường hợp, chúng cũng nhanh hơn
2. 14. 3 nhược điểm
Có thể trông lạ đối với các nhà phát triển C/C++
2. 14. 4 Quyết định
Sử dụng sai “ngầm” nếu có thể, e. g. ,
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
94 thay vì def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
95. Có một vài cảnh báo mà bạn nên ghi nhớ mặc dùLuôn sử dụng
96 [hoặcdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
97] để kiểm tra giá trịdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
98. e. g. , khi kiểm tra xem một biến hoặc đối số mặc định làdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
98 có được đặt thành một số giá trị khác không. Giá trị khác có thể là một giá trị sai trong ngữ cảnh booleandef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Không bao giờ so sánh một biến boolean với
92 bằng cách sử dụngdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
01. Sử dụngfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
02 để thay thế. Nếu bạn cần phân biệtfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
92 vớidef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
98 thì hãy xâu chuỗi các biểu thức, chẳng hạn nhưdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
05from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
Đối với các chuỗi [chuỗi, danh sách, bộ dữ liệu], hãy sử dụng thực tế là các chuỗi trống là sai, do đó,
06 vàfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
07 được ưu tiên hơn so vớifrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
08 vàfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
09 tương ứngfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
Khi xử lý các số nguyên, sai ẩn có thể gây ra nhiều rủi ro hơn là lợi ích [i. e. , vô tình xử lý
98 thành 0]. Bạn có thể so sánh một giá trị đã biết là một số nguyên [và không phải là kết quả củadef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
11] với số nguyên 0from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
6def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
7def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Lưu ý rằng
12 [tôi. e. ,from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
13 dưới dạng chuỗi] đánh giá là truefrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
Lưu ý rằng các mảng Numpy có thể đưa ra một ngoại lệ trong ngữ cảnh boolean ngầm định. Ưu tiên thuộc tính
14 khi kiểm tra tính không của mộtfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
15 [e. g.from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
16]from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
2. 16 Phạm vi từ vựng
Được rồi để sử dụng
2. 16. 1 Định nghĩa
Một hàm Python lồng nhau có thể tham chiếu đến các biến được xác định trong các hàm kèm theo, nhưng không thể gán cho chúng. Các liên kết biến được giải quyết bằng cách sử dụng phạm vi từ vựng, nghĩa là dựa trên văn bản chương trình tĩnh. Bất kỳ sự gán nào cho một tên trong một khối sẽ khiến Python coi tất cả các tham chiếu đến tên đó là một biến cục bộ, ngay cả khi việc sử dụng có trước sự gán. Nếu một khai báo toàn cầu xảy ra, tên được coi là một biến toàn cầu
Một ví dụ về việc sử dụng tính năng này là
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
82. 16. 2 Ưu điểm
Thường dẫn đến mã rõ ràng hơn, thanh lịch hơn. Đặc biệt an ủi các lập trình viên Lisp và Scheme [và Haskell, ML và…] có kinh nghiệm
2. 16. 3 nhược điểm
Có thể dẫn đến các lỗi khó hiểu. Chẳng hạn như ví dụ này dựa trên PEP-0227
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
9Vì vậy,
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
17 sẽ in ra from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
18, không phải là from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
192. 16. 4 Quyết định
Được rồi để sử dụng
2. 17 Trình trang trí hàm và phương thức
Sử dụng decorators một cách thận trọng khi có một lợi thế rõ ràng. Tránh
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
20 và hạn chế sử dụng from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
212. 17. 1 Định nghĩa
[một. k. một “ký hiệu
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
22”]. Một trình trang trí phổ biến là def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
91, được sử dụng để chuyển đổi các phương thức thông thường thành các thuộc tính được tính toán động. Tuy nhiên, cú pháp của trình trang trí cũng cho phép các trình trang trí do người dùng định nghĩa. Cụ thể, đối với một số chức năng from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
24, điều nàyfrom sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
0tương đương với
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
12. 17. 2 Ưu điểm
Chỉ định một cách trang nhã một số chuyển đổi trên một phương thức;
2. 17. 3 nhược điểm
Trình trang trí có thể thực hiện các thao tác tùy ý trên đối số của hàm hoặc trả về giá trị, dẫn đến hành vi ngầm đáng ngạc nhiên. Ngoài ra, các trình trang trí thực thi tại thời điểm xác định đối tượng. Đối với các đối tượng cấp mô-đun [lớp, chức năng mô-đun,…] điều này xảy ra tại thời điểm nhập. Lỗi trong mã trang trí hầu như không thể phục hồi từ
2. 17. 4 Quyết định
Sử dụng decorators một cách thận trọng khi có một lợi thế rõ ràng. Người trang trí phải tuân theo các nguyên tắc nhập và đặt tên giống như các chức năng. Trình trang trí pydoc phải nêu rõ rằng chức năng này là một trình trang trí. Viết bài kiểm tra đơn vị cho người trang trí
Tránh các phụ thuộc bên ngoài trong chính trình trang trí [e. g. không dựa vào tệp, ổ cắm, kết nối cơ sở dữ liệu, v.v. ], vì chúng có thể không khả dụng khi trình trang trí chạy [tại thời điểm nhập, có thể từ
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25 hoặc các công cụ khác]. Một trình trang trí được gọi với các tham số hợp lệ phải [càng nhiều càng tốt] được đảm bảo thành công trong mọi trường hợpTrình trang trí là trường hợp đặc biệt của “mã cấp cao nhất” - xem để thảo luận thêm
Không bao giờ sử dụng
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
20 trừ khi bị buộc phải tích hợp với API được xác định trong thư viện hiện có. Thay vào đó hãy viết một hàm cấp mô-đunChỉ sử dụng
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
21 khi viết một hàm tạo có tên hoặc một quy trình dành riêng cho lớp để sửa đổi trạng thái chung cần thiết, chẳng hạn như bộ đệm trên toàn bộ quy trình2. 18 luồng
Không dựa vào tính nguyên tử của các loại tích hợp
Mặc dù các kiểu dữ liệu tích hợp sẵn của Python, chẳng hạn như từ điển, dường như có các hoạt động nguyên tử, nhưng có một số trường hợp chúng không phải là nguyên tử [e. g. nếu
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
28 hoặc from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
29 được triển khai dưới dạng phương thức Python] và không nên dựa vào tính nguyên tử của chúng. Bạn cũng không nên dựa vào phép gán biến nguyên tử [vì điều này lại phụ thuộc vào từ điển]Sử dụng kiểu dữ liệu
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
30 của mô-đun Hàng đợi làm cách ưu tiên để giao tiếp dữ liệu giữa các luồng. Nếu không, hãy sử dụng mô-đun luồng và các nguyên hàm khóa của nó. Ưu tiên các biến điều kiện và from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
31 thay vì sử dụng các khóa cấp thấp hơn2. 19 Tính năng nguồn
Tránh các tính năng này
2. 19. 1 Definition
Python là một ngôn ngữ cực kỳ linh hoạt và cung cấp cho bạn nhiều tính năng ưa thích như siêu dữ liệu tùy chỉnh, quyền truy cập vào mã byte, biên dịch nhanh, kế thừa động, sửa chữa đối tượng, hack nhập, phản ánh [e. g. some uses of
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
32], modification of system internals, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
33 methods implementing customized cleanup, etc2. 19. 2 Ưu điểm
Đây là những tính năng ngôn ngữ mạnh mẽ. Họ có thể làm cho mã của bạn gọn hơn
2. 19. 3 nhược điểm
Rất hấp dẫn khi sử dụng những tính năng “hay ho” này khi chúng không thực sự cần thiết. Khó đọc, hiểu và gỡ lỗi mã đang sử dụng các tính năng bất thường bên dưới. Thoạt đầu có vẻ không phải như vậy [đối với tác giả gốc], nhưng khi xem lại mã, nó có xu hướng khó hơn mã dài hơn nhưng đơn giản
2. 19. 4 Quyết định
Avoid these features in your code
Standard library modules and classes that internally use these features are okay to use [for example,
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
34, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
35, and from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
36]2. 20 Modern Python. từ __future__ nhập khẩu
New language version semantic changes may be gated behind a special future import to enable them on a per-file basis within earlier runtimes
2. 20. 1 Definition
Being able to turn on some of the more modern features via
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
37 statements allows early use of features from expected future Python versions2. 20. 2 Pros
This has proven to make runtime version upgrades smoother as changes can be made on a per-file basis while declaring compatibility and preventing regressions within those files. Modern code is more maintainable as it is less likely to accumulate technical debt that will be problematic during future runtime upgrades
2. 20. 3 Cons
Such code may not work on very old interpreter versions prior to the introduction of the needed future statement. Nhu cầu này phổ biến hơn trong các dự án hỗ trợ rất nhiều môi trường
2. 20. 4 Decision
from __future__ importsUse of
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
37 statements is encouraged. It allows a given source file to start using more modern Python syntax features today. Once you no longer need to run on a version where the features are hidden behind a from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
39 import, feel free to remove those linesIn code that may execute on versions as old as 3. 5 rather than >= 3. 7, import
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
2Để biết thêm thông tin, hãy đọc tài liệu định nghĩa câu lệnh tương lai của Python
Vui lòng không xóa các mục nhập này cho đến khi bạn tin rằng mã này chỉ được sử dụng trong một môi trường đủ hiện đại. Ngay cả khi bạn hiện không sử dụng tính năng mà một tính năng nhập cụ thể trong tương lai cho phép trong mã của bạn hôm nay, thì việc giữ nguyên tính năng này trong tệp sẽ ngăn việc vô tình sửa đổi mã sau này tùy thuộc vào hành vi cũ hơn
Sử dụng các câu lệnh nhập khẩu
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
40 khác khi bạn thấy phù hợp2. 21 Loại mã chú thích
Bạn có thể chú thích mã Python bằng gợi ý loại theo PEP-484 và kiểm tra loại mã khi xây dựng bằng công cụ kiểm tra loại như pytype
Loại chú thích có thể trong nguồn hoặc trong một. Bất cứ khi nào có thể, chú thích nên ở trong nguồn. Sử dụng tệp pyi cho bên thứ ba hoặc mô-đun mở rộng
2. 21. 1 Định nghĩa
Chú thích kiểu [hoặc "gợi ý kiểu"] dành cho hàm hoặc đối số phương thức và giá trị trả về
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
3Bạn cũng có thể khai báo loại biến bằng cú pháp PEP-526 tương tự
2. 21. 2 Ưu điểm
Loại chú thích cải thiện khả năng đọc và bảo trì mã của bạn. Trình kiểm tra loại sẽ chuyển đổi nhiều lỗi thời gian chạy thành lỗi thời gian xây dựng và giảm khả năng sử dụng của bạn
2. 21. 3 nhược điểm
Bạn sẽ phải cập nhật các khai báo kiểu. Bạn có thể thấy lỗi loại mà bạn nghĩ là mã hợp lệ. Việc sử dụng bộ kiểm tra loại có thể làm giảm khả năng sử dụng của bạn
2. 21. 4 Quyết định
Bạn được khuyến khích bật phân tích kiểu Python khi cập nhật mã. Khi thêm hoặc sửa đổi API công khai, hãy bao gồm các chú thích loại và cho phép kiểm tra qua pytype trong hệ thống xây dựng. Vì phân tích tĩnh còn tương đối mới đối với Python, chúng tôi thừa nhận rằng các tác dụng phụ không mong muốn [chẳng hạn như các loại được suy luận sai] có thể ngăn một số dự án áp dụng. Trong những trường hợp đó, các tác giả được khuyến khích thêm nhận xét bằng TODO hoặc liên kết đến lỗi mô tả [các] sự cố hiện đang ngăn cản việc áp dụng chú thích loại trong tệp BUILD hoặc trong chính mã nếu phù hợp
3 quy tắc kiểu Python
3. 1 dấu chấm phẩy
Không kết thúc dòng của bạn bằng dấu chấm phẩy và không sử dụng dấu chấm phẩy để đặt hai câu lệnh trên cùng một dòng
3. 2 Chiều dài dòng
Độ dài dòng tối đa là 80 ký tự
Ngoại lệ rõ ràng đối với giới hạn 80 ký tự
- Báo cáo nhập khẩu dài
- URL, tên đường dẫn hoặc cờ dài trong nhận xét
- Các hằng số cấp mô-đun chuỗi dài không chứa khoảng trắng sẽ gây bất tiện khi chia thành các dòng như URL hoặc tên đường dẫn
- Pylint vô hiệu hóa bình luận. [e. g.
41]from sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
- Pylint vô hiệu hóa bình luận. [e. g.
Không sử dụng tiếp tục dòng gạch chéo ngược ngoại trừ câu lệnh
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 yêu cầu ba trình quản lý ngữ cảnh trở lênTận dụng Python. Nếu cần, bạn có thể thêm một cặp dấu ngoặc đơn xung quanh một biểu thức
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
4Khi một chuỗi ký tự không vừa trên một dòng, hãy sử dụng dấu ngoặc đơn để nối dòng ẩn
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
5Trong các nhận xét, hãy đặt các URL dài trên dòng riêng của chúng nếu cần
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
6from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
7Có thể sử dụng tiếp tục dấu gạch chéo ngược khi xác định câu lệnh
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 với ba trình quản lý ngữ cảnh trở lên. Đối với hai trình quản lý bối cảnh, hãy sử dụng câu lệnh from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 lồng nhaufrom sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
8from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
9Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
0Lưu ý về sự thụt đầu dòng của các phần tử trong các ví dụ tiếp tục dòng ở trên;
Trong tất cả các trường hợp khác khi một dòng vượt quá 80 ký tự và trình định dạng tự động yapf không giúp đưa dòng xuống dưới giới hạn, thì dòng đó được phép vượt quá mức tối đa này. Các tác giả được khuyến khích ngắt dòng theo cách thủ công theo ghi chú ở trên khi thấy hợp lý
3. 3 dấu ngoặc đơn
Sử dụng dấu ngoặc đơn một cách tiết kiệm
Nó là tốt, mặc dù không bắt buộc, để sử dụng dấu ngoặc đơn xung quanh bộ dữ liệu. Không sử dụng chúng trong các câu lệnh trả về hoặc câu lệnh có điều kiện trừ khi sử dụng dấu ngoặc đơn để tiếp tục dòng ngụ ý hoặc để chỉ ra một bộ
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
1Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
23. 4 Thụt đầu dòng
Thụt lề các khối mã của bạn với 4 dấu cách
Không bao giờ sử dụng các tab. Việc tiếp tục dòng ngụ ý phải căn chỉnh các phần tử được bao theo chiều dọc [xem] hoặc sử dụng thụt lề 4 dấu cách treo. Dấu ngoặc đóng [tròn, vuông hoặc cong] có thể được đặt ở cuối biểu thức hoặc trên các dòng riêng biệt, nhưng sau đó phải được thụt vào giống như dòng có dấu ngoặc mở tương ứng
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
3Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
43. 4. 1 Dấu phẩy ở cuối dãy các mục?
Dấu phẩy ở cuối trong chuỗi các mục chỉ được khuyến nghị khi mã thông báo vùng chứa đóng
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
45, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
46 hoặc from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
47 không xuất hiện trên cùng một dòng với phần tử cuối cùng. Sự hiện diện của dấu phẩy ở cuối cũng được sử dụng như một gợi ý cho trình định dạng tự động mã Python YAPF của chúng tôi để hướng dẫn nó tự động định dạng vùng chứa các mục thành một mục trên mỗi dòng khi có _from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
48 sau phần tử cuối cùngYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
53. 5 dòng trống
Hai dòng trống giữa các định nghĩa cấp cao nhất, có thể là định nghĩa hàm hoặc lớp. Một dòng trống giữa các định nghĩa phương thức và giữa chuỗi tài liệu của
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
49 và phương thức đầu tiên. Không có dòng trống nào sau dòng from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
50. Sử dụng các dòng trống đơn khi bạn đánh giá phù hợp trong các hàm hoặc phương thứcCác dòng trống không cần phải được neo vào định nghĩa. Ví dụ: các nhận xét liên quan ngay trước các định nghĩa hàm, lớp và phương thức có thể có ý nghĩa. Cân nhắc xem nhận xét của bạn có thể hữu ích hơn như một phần của chuỗi tài liệu không
3. 6 Khoảng trắng
Thực hiện theo các quy tắc đánh máy tiêu chuẩn để sử dụng khoảng trắng xung quanh dấu chấm câu
No whitespace inside parentheses, brackets or braces
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
6Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
7No whitespace before a comma, semicolon, or colon. Do use whitespace after a comma, semicolon, or colon, except at the end of the line
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
8Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
9No whitespace before the open paren/bracket that starts an argument list, indexing or slicing
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
0Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
1No trailing whitespace
Surround binary operators with a single space on either side for assignment [
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51], comparisons [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
52], and Booleans [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
53]. Use your better judgment for the insertion of spaces around arithmetic operators [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
54, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
55, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
56, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
57, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
58, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
59, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
60, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
22]Never use spaces around
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51 when passing keyword arguments or defining a default parameter value, with one exception. , do use spaces around the from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51 for the default parameter valueYes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
2Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
3Don’t use spaces to vertically align tokens on consecutive lines, since it becomes a maintenance burden [applies to
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
64, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
65, from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51, etc. ]Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
4Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
53. 7 Shebang Line
Most
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
67 files do not need to start with a from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
68 line. Start the main file of a program with from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
69 [to support virtualenvs] or from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
70 per PEP-394This line is used by the kernel to find the Python interpreter, but is ignored by Python when importing modules. It is only necessary on a file intended to be executed directly
Be sure to use the right style for module, function, method docstrings and inline comments
3. 8. 1 Docstrings
Python uses docstrings to document code. A docstring is a string that is the first statement in a package, module, class or function. These strings can be extracted automatically through the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
71 member of the object and are used by from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25. [Try running from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25 on your module to see how it looks. ] Always use the three double-quote from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
74 format for docstrings [per PEP 257]. A docstring should be organized as a summary line [one physical line not exceeding 80 characters] terminated by a period, question mark, or exclamation point. When writing more [encouraged], this must be followed by a blank line, followed by the rest of the docstring starting at the same cursor position as the first quote of the first line. There are more formatting guidelines for docstrings below3. 8. 2 Modules
Every file should contain license boilerplate. Choose the appropriate boilerplate for the license used by the project [for example, Apache 2. 0, BSD, LGPL, GPL]
Files should start with a docstring describing the contents and usage of the module
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
63. 8. 2. 1 Test modulesModule-level docstrings for test files are not required. They should be included only when there is additional information that can be provided
Examples include some specifics on how the test should be run, an explanation of an unusual setup pattern, dependency on the external environment, and so on
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
7Docstrings that do not provide any new information should not be used
3. 8. 3 Hàm và Phương thức
In this section, “function” means a method, function, generator, or property
A docstring is mandatory for every function that has one or more of the following properties
- being part of the public API
- nontrivial size
- non-obvious logic
A docstring should give enough information to write a call to the function without reading the function’s code. The docstring should describe the function’s calling syntax and its semantics, but generally not its implementation details, unless those details are relevant to how the function is to be used. For example, a function that mutates one of its arguments as a side effect should note that in its docstring. Otherwise, subtle but important details of a function’s implementation that are not relevant to the caller are better expressed as comments alongside the code than within the function’s docstring
The docstring may be descriptive-style [
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
75] or imperative-style [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
76], but the style should be consistent within a file. The docstring for a def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
91 data descriptor should use the same style as the docstring for an attribute or a [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
78, rather than from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
79]A method that overrides a method from a base class may have a simple docstring sending the reader to its overridden method’s docstring, such as
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
80. The rationale is that there is no need to repeat in many places documentation that is already present in the base method’s docstring. However, if the overriding method’s behavior is substantially different from the overridden method, or details need to be provided [e. g. , documenting additional side effects], a docstring with at least those differences is required on the overriding methodCertain aspects of a function should be documented in special sections, listed below. Each section begins with a heading line, which ends with a colon. All sections other than the heading should maintain a hanging indent of two or four spaces [be consistent within a file]. These sections can be omitted in cases where the function’s name and signature are informative enough that it can be aptly described using a one-line docstring
List each parameter by name. A description should follow the name, and be separated by a colon followed by either a space or newline. If the description is too long to fit on a single 80-character line, use a hanging indent of 2 or 4 spaces more than the parameter name [be consistent with the rest of the docstrings in the file]. The description should include required type[s] if the code does not contain a corresponding type annotation. If a function acceptsfrom sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
81 [variable length argument lists] and/or from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
82 [arbitrary keyword arguments], they should be listed as from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
81 and from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
82. Describe the type and semantics of the return value. If the function only returns None, this section is not required. It may also be omitted if the docstring starts with Returns or Yields [e. g. from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
85] and the opening sentence is sufficient to describe the return value. Do not imitate ‘NumPy style’ [example], which frequently documents a tuple return value as if it were multiple return values with individual names [never mentioning the tuple]. Instead, describe such a return value as. “Returns. A tuple [mat_a, mat_b], where mat_a is …, and …”. The auxiliary names in the docstring need not necessarily correspond to any internal names used in the function body [as those are not part of the API]. List all exceptions that are relevant to the interface followed by a description. Use a similar exception name + colon + space or newline and hanging indent style as described in Args. You should not document exceptions that get raised if the API specified in the docstring is violated [because this would paradoxically make behavior under violation of the API part of the API]Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
8Similarly, this variation on
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
86 with a line break is also allowedYes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
93. 8. 4 Classes
Classes should have a docstring below the class definition describing the class. If your class has public attributes, they should be documented here in an
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
87 section and follow the same formatting as a sectionNo:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
0All class docstrings should start with a one-line summary that describes what the class instance represents. This implies that subclasses of
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
60 should also describe what the exception represents, and not the context in which it might occur. Chuỗi tài liệu lớp không được lặp lại thông tin không cần thiết, chẳng hạn như lớp là một lớpNo:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
1No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
23. 8. 5 Block and Inline Comments
The final place to have comments is in tricky parts of the code. If you’re going to have to explain it at the next code review, you should comment it now. Complicated operations get a few lines of comments before the operations commence. Non-obvious ones get comments at the end of the line
No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
3Để cải thiện mức độ dễ đọc, các nhận xét này phải bắt đầu cách mã ít nhất 2 khoảng trắng với ký tự nhận xét
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
65, theo sau là ít nhất một khoảng trắng trước văn bản của chính nhận xét đóMặt khác, không bao giờ mô tả mã. Assume the person reading the code knows Python [though not what you’re trying to do] better than you do
No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
43. 8. 6 Punctuation, Spelling, and Grammar
Pay attention to punctuation, spelling, and grammar; it is easier to read well-written comments than badly written ones
Comments should be as readable as narrative text, with proper capitalization and punctuation. In many cases, complete sentences are more readable than sentence fragments. Shorter comments, such as comments at the end of a line of code, can sometimes be less formal, but you should be consistent with your style
Although it can be frustrating to have a code reviewer point out that you are using a comma when you should be using a semicolon, it is very important that source code maintain a high level of clarity and readability. Dấu chấm câu, chính tả và ngữ pháp phù hợp giúp đạt được mục tiêu đó
3. 10 Strings
Use an , the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
59 operator, or the from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
92 method for formatting strings, even when the parameters are all strings. Use your best judgment to decide between string formatting options. A single join with from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
54 is okay but do not format with from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
54No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
5No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
6Avoid using the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
54 and from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
96 operators to accumulate a string within a loop. In some conditions, accumulating a string with addition can lead to quadratic rather than linear running time. Although common accumulations of this sort may be optimized on CPython, that is an implementation detail. The conditions under which an optimization applies are not easy to predict and may change. Instead, add each substring to a list and from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
97 the list after the loop terminates, or write each substring to an from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
98 buffer. These techniques consistently have amortized-linear run time complexityNo:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
7No:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
8Be consistent with your choice of string quote character within a file. Pick
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
99 or Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
00 and stick with it. It is okay to use the other quote character on a string to avoid the need to backslash-escape quote characters within the stringNo:
# Unclear what module the author wanted and what will be imported. The actual
# import behavior depends on external factors controlling sys.path.
# Which possible jodie module did the author intend to import?
import jodie
9Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
0Prefer
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
74 for multi-line strings rather than Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
02. Projects may choose to use Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
02 for all non-docstring multi-line strings if and only if they also use from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
99 for regular strings. Docstrings must use from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
74 regardlessMulti-line strings do not flow with the indentation of the rest of the program. If you need to avoid embedding extra space in the string, use either concatenated single-line strings or a multi-line string with to remove the initial space on each line
Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
1Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
2Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
3Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
4Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
53. 10. 1 Logging
For logging functions that expect a pattern-string [with %-placeholders] as their first argument. Always call them with a string literal [not an f-string. ] as their first argument with pattern-parameters as subsequent arguments. Một số triển khai ghi nhật ký thu thập chuỗi mẫu chưa được mở rộng dưới dạng trường có thể truy vấn. It also prevents spending time rendering a message that no logger is configured to output
Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
6Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
7Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
83. 10. 2 Error Messages
Error messages [such as. message strings on exceptions like
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
54, or messages shown to the user] should follow three guidelinesThe message needs to precisely match the actual error condition
Interpolated pieces need to always be clearly identifiable as such
They should allow simple automated processing [e. g. grepping]
Yes:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
Raises:
ConnectionError: If no available port is found.
"""
if minimum < 1024:
# Note that this raising of ValueError is not mentioned in the doc
# string's "Raises:" section because it is not appropriate to
# guarantee this specific behavioral reaction to API misuse.
raise ValueError[f'Min. port must be at least 1024, not {minimum}.']
port = self._find_next_open_port[minimum]
if port is None:
raise ConnectionError[
f'Could not connect to service on port {minimum} or higher.']
assert port >= minimum, [
f'Unexpected port {port} when minimum was {minimum}.']
return port
9No:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
03. 11 Files, Sockets, and similar Stateful Resources
Explicitly close files and sockets when done with them. This rule naturally extends to closeable resources that internally use sockets, such as database connections, and also other resources that need to be closed down in a similar fashion. To name only a few examples, this also includes mmap mappings, h5py File objects, and matplotlib. pyplot figure windows
Leaving files, sockets or other such stateful objects open unnecessarily has many downsides
- They may consume limited system resources, such as file descriptors. Code that deals with many such objects may exhaust those resources unnecessarily if they’re not returned to the system promptly after use
- Holding files open may prevent other actions such as moving or deleting them, or unmounting a filesystem
- Files and sockets that are shared throughout a program may inadvertently be read from or written to after logically being closed. If they are actually closed, attempts to read or write from them will raise exceptions, making the problem known sooner
Furthermore, while files and sockets [and some similarly behaving resources] are automatically closed when the object is destructed, coupling the lifetime of the object to the state of the resource is poor practice
- There are no guarantees as to when the runtime will actually invoke the
33 method. Different Python implementations use different memory management techniques, such as delayed garbage collection, which may increase the object’s lifetime arbitrarily and indefinitelyfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
- Unexpected references to the file, e. g. in globals or exception tracebacks, may keep it around longer than intended
Relying on finalizers to do automatic cleanup that has observable side effects has been rediscovered over and over again to lead to major problems, across many decades and multiple languages [see e. g. this article for Java]
The preferred way to manage files and similar resources is using the
No:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
1For file-like objects that do not support the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 statement, use Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
11No:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
2In rare cases where context-based resource management is infeasible, code documentation must explain clearly how resource lifetime is managed
Use
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 comments for code that is temporary, a short-term solution, or good-enough but not perfectA
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 comment begins with the word Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 in all caps, and a parenthesized context identifier. Ideally a bug reference, sometimes a username. A bug reference like Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
15 is preferable, because bugs are tracked and have follow-up comments, whereas individuals move around and may lose context over time. The Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 is followed by an explanation of what there is to doThe purpose is to have a consistent
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 format that can be searched to find out how to get more details. A Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 is not a commitment that the person referenced will fix the problem. Thus when you create a Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 with a username, it is almost always your own username that is givenNo:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
3If your
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
12 is of the form “At a future date do something” make sure that you either include a very specific date [“Fix by November 2009”] or a very specific event [“Remove this code when all clients can handle XML responses. ”] that future code maintainers will comprehend3. 13 Imports formatting
Imports should be on separate lines; there are
E. g
No:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
4Imports are always put at the top of the file, just after any module comments and docstrings and before module globals and constants. Nhập khẩu nên được nhóm từ chung chung nhất đến ít chung chung nhất
Python future import statements. Ví dụ
5No: def connect_to_next_port[self, minimum: int] -> int: """Connects to the next available port. Args: minimum: A port value greater or equal to 1024. Returns: The new minimum port. """ assert minimum >= 1024, 'Minimum port must be at least 1024.' port = self._find_next_open_port[minimum] assert port is not None return port
See for more information about those
Python standard library imports. For example
third-party module or package imports. For example
Code repository sub-package imports. For example
6No: def connect_to_next_port[self, minimum: int] -> int: """Connects to the next available port. Args: minimum: A port value greater or equal to 1024. Returns: The new minimum port. """ assert minimum >= 1024, 'Minimum port must be at least 1024.' port = self._find_next_open_port[minimum] assert port is not None return port
Deprecated. application-specific imports that are part of the same top level sub-package as this file. For example
7No: def connect_to_next_port[self, minimum: int] -> int: """Connects to the next available port. Args: minimum: A port value greater or equal to 1024. Returns: The new minimum port. """ assert minimum >= 1024, 'Minimum port must be at least 1024.' port = self._find_next_open_port[minimum] assert port is not None return port
You may find older Google Python Style code doing this, but it is no longer required. New code is encouraged not to bother with this. Simply treat application-specific sub-package imports the same as other sub-package imports
Within each grouping, imports should be sorted lexicographically, ignoring case, according to each module’s full package path [the
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
23 in Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
24]. Code may optionally place a blank line between import sectionsNo:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
83. 14 Statements
Generally only one statement per line
However, you may put the result of a test on the same line as the test only if the entire statement fits on one line. In particular, you can never do so with
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
63/def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
64 since the def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
63 and def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
64 can’t both fit on the same line, and you can only do so with an Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
29 if there is no Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
30No:
def connect_to_next_port[self, minimum: int] -> int:
"""Connects to the next available port.
Args:
minimum: A port value greater or equal to 1024.
Returns:
The new minimum port.
"""
assert minimum >= 1024, 'Minimum port must be at least 1024.'
port = self._find_next_open_port[minimum]
assert port is not None
return port
93. 15 Getters and Setters
Getter and setter functions [also called accessors and mutators] should be used when they provide a meaningful role or behavior for getting or setting a variable’s value
In particular, they should be used when getting or setting the variable is complex or the cost is significant, either currently or in a reasonable future
If, for example, a pair of getters/setters simply read and write an internal attribute, the internal attribute should be made public instead. By comparison, if setting a variable means some state is invalidated or rebuilt, it should be a setter function. The function invocation hints that a potentially non-trivial operation is occurring. Alternatively, may be an option when simple logic is needed, or refactoring to no longer need getters and setters
Getters and setters should follow the guidelines, such as
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
31 and Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
32If the past behavior allowed access through a property, do not bind the new getter/setter functions to the property. Any code still attempting to access the variable by the old method should break visibly so they are made aware of the change in complexity
3. 16 Naming
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
33, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
34, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
35, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
36, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
37, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
38, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
39, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
40, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
41, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
42, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
43, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
44, Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
45Function names, variable names, and filenames should be descriptive; avoid abbreviation. In particular, do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word
Always use a
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
67 filename extension. Never use dashes3. 16. 1 Names to Avoid
single character names, except for specifically allowed cases
- counters or iterators [e. g.
47,Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
48,Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
49,Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
50, et al. ]Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
51 as an exception identifier inYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
52 statementsYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
53 as a file handle inYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
42 statementsfrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
- private with no constraints [e. g.
56,Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
57,Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
58]Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
Please be mindful not to abuse single-character naming. Generally speaking, descriptiveness should be proportional to the name’s scope of visibility. For example,
47 might be a fine name for 5-line code block but within multiple nested scopes, it is likely too vagueYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
- counters or iterators [e. g.
dashes [
55] in any package/module namefrom sound.effects import echo ... echo.EchoFilter[input, output, delay=0.7, atten=4]
61 tên [được đặt trước bởi Python]Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
offensive terms
names that needlessly include the type of the variable [for example.
62]Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
3. 16. 2 Naming Conventions
“Internal” means internal to a module, or protected or private within a class
Prepending a single underscore [
28] has some support for protecting module variables and functions [linters will flag protected member access]def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
Prepending a double underscore [
64 aka “dunder”] to an instance variable or method effectively makes the variable or method private to its class [using name mangling]; we discourage its use as it impacts readability and testability, and isn’t really private. Prefer a single underscoreYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
Place related classes and top-level functions together in a module. Unlike Java, there is no need to limit yourself to one class per module
Use CapWords for class names, but lower_with_under. py for module names. Although there are some old modules named CapWords. py, this is now discouraged because it’s confusing when the module happens to be named after a class. [“wait – did I write
65 orYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
66?”]Yes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
Underscores may appear in unittest method names starting with
67 to separate logical components of the name, even if those components use CapWords. One possible pattern isYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
68; for exampleYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
69 is okay. There is no One Correct Way to name test methodsYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
3. 16. 3 File Naming
Python filenames must have a
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
67 extension and must not contain dashes [from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
55]. This allows them to be imported and unittested. If you want an executable to be accessible without the extension, use a symbolic link or a simple bash wrapper containing Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
723. 16. 4 Guidelines derived from Guido’s Recommendations
TypePublicInternalPackagesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
73ModulesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
73Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
75ClassesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
76Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
77ExceptionsYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
76FunctionsYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
79Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
80Global/Class ConstantsYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
81Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
82Global/Class VariablesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
73Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
75Instance VariablesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
73Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
75 [protected]Method NamesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
79Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
80 [protected]Function/Method ParametersYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
73Local VariablesYes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
733. 16. 5 Mathematical Notation
For mathematically heavy code, short variable names that would otherwise violate the style guide are preferred when they match established notation in a reference paper or algorithm. When doing so, reference the source of all naming conventions in a comment or docstring or, if the source is not accessible, clearly document the naming conventions. Prefer PEP8-compliant
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
91 for public APIs, which are much more likely to be encountered out of context3. 17 Main
In Python,
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25 as well as unit tests require modules to be importable. If a file is meant to be used as an executable, its main functionality should be in a Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
93 function, and your code should always check Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
94 before executing your main program, so that it is not executed when the module is importedWhen using absl, use
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
95Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
0Otherwise, use
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
1All code at the top level will be executed when the module is imported. Be careful not to call functions, create objects, or perform other operations that should not be executed when the file is being
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25ed3. 18 Function length
Prefer small and focused functions
We recognize that long functions are sometimes appropriate, so no hard limit is placed on function length. If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program
Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code
You could find long and complicated functions when working with some code. Do not be intimidated by modifying existing code. if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several different contexts, consider breaking up the function into smaller and more manageable pieces
3. 19 Type Annotations
3. 19. 1 General Rules
Familiarize yourself with PEP-484
Trong các phương thức, chỉ chú thích
73 hoặcdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
74 nếu cần thiết cho thông tin loại phù hợp. e. g. ,def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
2Yes: result = [mapping_expr for value in iterable if filter_expr] result = [{'key': value} for value in iterable if a_long_filter_expression[value]] result = [complicated_transform[x] for x in iterable if predicate[x]] descriptive_name = [ transform[{'key': key, 'value': value}, color='black'] for key, value in generate_iterable[some_input] if complicated_condition_is_met[key, value] ] result = [] for x in range[10]: for y in range[5]: if x * y > 10: result.append[[x, y]] return {x: complicated_transform[x] for x in long_generator_function[parameter] if x is not None} squares_generator = [x**2 for x in range[10]] unique_names = {user.name for user in users if user is not None} eat[jelly_bean for jelly_bean in jelly_beans if jelly_bean.color == 'black']
Similarly, don’t feel compelled to annotate the return value of
99 [whereYes: # Reference absl.flags in code with the complete name [verbose]. import absl.flags from doctor.who import jodie _FOO = absl.flags.DEFINE_string[...]
98 is the only valid option]def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
If any other variable or a returned type should not be expressed, use
01Yes: # Reference flags in code with just the module name [common]. from absl import flags from doctor.who import jodie _FOO = flags.DEFINE_string[...]
You are not required to annotate all the functions in a module
- At least annotate your public APIs
- Use judgment to get to a good balance between safety and clarity on the one hand, and flexibility on the other
- Annotate code that is prone to type-related errors [previous bugs or complexity]
- Annotate code that is hard to understand
- Annotate code as it becomes stable from a types perspective. In many cases, you can annotate all the functions in mature code without losing too much flexibility
3. 19. 2 Line Breaking
Cố gắng tuân theo các quy tắc hiện có
Sau khi chú thích, nhiều chữ ký hàm sẽ trở thành “mỗi dòng một tham số”. Để đảm bảo kiểu trả về cũng được cung cấp dòng riêng, có thể đặt dấu phẩy sau tham số cuối cùng
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
3Luôn ưu tiên ngắt giữa các biến và không, ví dụ, giữa tên biến và chú thích loại. Tuy nhiên, nếu mọi thứ phù hợp trên cùng một dòng, hãy tiếp tục
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
4Nếu tổ hợp tên hàm, tham số cuối cùng và kiểu trả về quá dài, hãy thụt lề 4 trong một dòng mới. When using line breaks, prefer putting each parameter and the return type on their own lines and aligning the closing parenthesis with the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
50Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
5Tùy chọn, kiểu trả về có thể được đặt trên cùng một dòng với tham số cuối cùng
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
6def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
18 cho phép bạn di chuyển dấu ngoặc đơn đóng sang một dòng mới và căn chỉnh với dòng mở đầu, nhưng điều này khó đọc hơnYes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
7Như trong các ví dụ trên, không muốn ngắt các loại. Tuy nhiên, đôi khi chúng quá dài để nằm trên một dòng [cố gắng giữ cho các loại phụ không bị gián đoạn]
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
8Nếu một tên và loại quá dài, hãy xem xét sử dụng một loại cho. Phương án cuối cùng là ngắt sau dấu hai chấm và thụt vào 4
Yes:
result = [mapping_expr for value in iterable if filter_expr]
result = [{'key': value} for value in iterable
if a_long_filter_expression[value]]
result = [complicated_transform[x]
for x in iterable if predicate[x]]
descriptive_name = [
transform[{'key': key, 'value': value}, color='black']
for key, value in generate_iterable[some_input]
if complicated_condition_is_met[key, value]
]
result = []
for x in range[10]:
for y in range[5]:
if x * y > 10:
result.append[[x, y]]
return {x: complicated_transform[x]
for x in long_generator_function[parameter]
if x is not None}
squares_generator = [x**2 for x in range[10]]
unique_names = {user.name for user in users if user is not None}
eat[jelly_bean for jelly_bean in jelly_beans
if jelly_bean.color == 'black']
9No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
03. 19. 3 Tuyên bố chuyển tiếp
Nếu bạn cần sử dụng một tên lớp [từ cùng một mô-đun] chưa được xác định – ví dụ: nếu bạn cần tên lớp bên trong phần khai báo của lớp đó hoặc nếu bạn sử dụng một lớp được xác định sau trong mã –
No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
1No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
23. 19. 4 giá trị mặc định
Theo , chỉ sử dụng khoảng trắng xung quanh
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51 cho các đối số có cả chú thích loại và giá trị mặc địnhNo:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
3No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
43. 19. 5 Không có Loại
Trong hệ thống kiểu Python,
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
06 là kiểu "hạng nhất" và vì mục đích đánh máy, def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
98 là bí danh của Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
06. Nếu một đối số có thể là def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
98, thì nó phải được khai báo. Bạn có thể sử dụng Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
10, nhưng nếu chỉ có một loại khác, hãy sử dụng Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
11Sử dụng
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
11 rõ ràng thay vì ngầm ẩn Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
11. Các phiên bản trước của PEP 484 cho phép Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
14 được hiểu là Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
15, nhưng đó không còn là hành vi được ưu tiên nữaNo:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
5No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
63. 19. 6 bí danh loại
Bạn có thể khai báo bí danh của các loại phức tạp. Tên của bí danh phải là CapWorded. Nếu bí danh chỉ được sử dụng trong mô-đun này, thì bí danh đó phải là _Private
Ví dụ: nếu tên của mô-đun cùng với tên của loại quá dài
No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
7Các ví dụ khác là các kiểu lồng nhau phức tạp và nhiều biến trả về từ một hàm [dưới dạng một bộ]
3. 19. 7 kiểu phớt lờ
Bạn có thể tắt kiểm tra loại trên một dòng bằng chú thích đặc biệt
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
16Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
17 có tùy chọn tắt đối với các lỗi cụ thể [tương tự như xơ vải]No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
83. 19. 8 biến gõ
Nếu một biến nội bộ có loại khó hoặc không thể suy luận, hãy chỉ định loại của biến đó bằng cách gán có chú thích - sử dụng dấu hai chấm và nhập giữa tên và giá trị biến [tương tự như được thực hiện với các đối số hàm có giá trị mặc định]No:
result = [complicated_transform[
x, some_argument=x+1]
for x in iterable if predicate[x]]
result = [[x, y] for x in range[10] for y in range[5] if x * y > 10]
return [[x, y, z]
for x in range[5]
for y in range[5]
if x != y
for z in range[5]
if y != z]
9Mặc dù bạn có thể thấy chúng còn lại trong cơ sở mã [chúng cần thiết trước Python 3. 6], không thêm bất kỳ cách sử dụng nào nữa của nhận xét Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
18 ở cuối dòngdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
003. 19. 9 Tuples vs Danh sách
Danh sách đã nhập chỉ có thể chứa các đối tượng thuộc một loại. Các bộ dữ liệu đã nhập có thể có một loại lặp lại duy nhất hoặc một số phần tử được đặt với các loại khác nhau. Cái sau thường được sử dụng làm kiểu trả về từ một hàm
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
013. 19. 10 LoạiVars
Hệ thống kiểu Python có. Chức năng nhà máy
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
55 là một cách phổ biến để sử dụng chúngThí dụ
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
02Một TypeVar có thể bị ràng buộc
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
03Biến loại được xác định trước phổ biến trong mô-đun
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
21 là Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
21. Sử dụng nó cho nhiều chú thích có thể là Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
22 hoặc Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
23 và tất cả phải cùng loạidef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
04TypeVar phải có tên mô tả, trừ khi nó đáp ứng tất cả các tiêu chí sau
- không thể nhìn thấy bên ngoài
- không bị hạn chế
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
05def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
063. 19. 11 loại chuỗi
Do not use
24 in new code. It’s only for Python 2/3 compatibilityYes: # Reference flags in code with just the module name [common]. from absl import flags from doctor.who import jodie _FOO = flags.DEFINE_string[...]
Use
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
23 for string/text data. For code that deals with binary data, use Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
22def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
07If all the string types of a function are always the same, for example if the return type is the same as the argument type in the code above, use
3. 19. 12 Imports For Typing
For symbols from the
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
21 and Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
22 modules used to support static analysis and type checking, always import the symbol itself. This keeps common annotations more concise and matches typing practices used around the world. Bạn rõ ràng được phép nhập nhiều lớp cụ thể trên một dòng từ các mô-đun Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
21 và Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
22. Exdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
08Given that this way of importing adds items to the local namespace, names in
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
21 or Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
22 should be treated similarly to keywords, and not be defined in your Python code, typed or not. If there is a collision between a type and an existing name in a module, import it using Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
33def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
09Prefer to use built-in types as annotations where available. Python supports type annotations using parametric container types via PEP-585, introduced in Python 3. 9
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
10NOTE. Người dùng Apache Beam nên tiếp tục nhập vùng chứa tham số từ
Yes:
# Reference absl.flags in code with the complete name [verbose].
import absl.flags
from doctor.who import jodie
_FOO = absl.flags.DEFINE_string[...]
21def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
113. 19. 13 Nhập khẩu có điều kiện
Chỉ sử dụng nhập có điều kiện trong các trường hợp đặc biệt khi phải tránh nhập bổ sung cần thiết để kiểm tra loại trong thời gian chạy. Mô hình này không được khuyến khích;
Các mục nhập chỉ cần thiết cho chú thích loại có thể được đặt trong một khối
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
35- Các loại được nhập có điều kiện cần được tham chiếu dưới dạng chuỗi, để tương thích chuyển tiếp với Python 3. 6 nơi các biểu thức chú thích thực sự được đánh giá
- Chỉ các thực thể được sử dụng duy nhất để nhập mới được xác định ở đây; . Nếu không, đó sẽ là lỗi thời gian chạy, vì mô-đun sẽ không được nhập vào thời gian chạy
- Khối phải ở ngay sau tất cả các lần nhập thông thường
- Không được có dòng trống nào trong danh sách nhập nhập
- Sắp xếp danh sách này như thể nó là một danh sách nhập thông thường
12def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str: del beans, eggs # Unused by vikings. return spam + spam + spam
3. 19. 14 phụ thuộc tuần hoàn
Circular dependencies that are caused by typing are code smells. Mã như vậy là một ứng cử viên tốt để tái cấu trúc. Mặc dù về mặt kỹ thuật, có thể giữ các phụ thuộc vòng tròn, nhưng các hệ thống xây dựng khác nhau sẽ không cho phép bạn làm như vậy vì mỗi mô-đun phải phụ thuộc vào mô-đun khác
Thay thế các mô-đun tạo nhập khẩu phụ thuộc vòng tròn bằng
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
01. Đặt một tên có ý nghĩa và sử dụng tên loại thực từ mô-đun này [bất kỳ thuộc tính nào của Any là Any]. Các định nghĩa bí danh phải được phân tách khỏi lần nhập cuối cùng bằng một dòngdef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
133. 19. 15 thuốc gốc
Khi chú thích, ưu tiên chỉ định tham số loại cho các loại chung;
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
14def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
15Nếu tham số loại tốt nhất cho một tên chung là
Yes:
# Reference flags in code with just the module name [common].
from absl import flags
from doctor.who import jodie
_FOO = flags.DEFINE_string[...]
01, hãy làm cho nó rõ ràng, nhưng hãy nhớ rằng trong nhiều trường hợp có thể phù hợp hơndef viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
16def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
del beans, eggs # Unused by vikings.
return spam + spam + spam
174 Lời Chia Tay
HÃY KIÊN NHẪN
Nếu bạn đang chỉnh sửa mã, hãy dành vài phút để xem mã xung quanh bạn và xác định phong cách của nó. Nếu họ sử dụng khoảng trắng xung quanh tất cả các toán tử số học của họ, thì bạn cũng nên. Nếu nhận xét của họ có các hộp dấu thăng nhỏ xung quanh, hãy làm cho nhận xét của bạn cũng có các hộp dấu thăng nhỏ xung quanh chúng
Mục đích của việc có các hướng dẫn về phong cách là có một vốn từ vựng chung về viết mã để mọi người có thể tập trung vào những gì bạn đang nói hơn là vào cách bạn nói. Chúng tôi trình bày các quy tắc phong cách toàn cầu ở đây để mọi người biết từ vựng, nhưng phong cách địa phương cũng rất quan trọng. Nếu mã bạn thêm vào một tệp trông khác hẳn so với mã hiện có xung quanh nó, nó sẽ khiến người đọc mất nhịp khi họ đọc nó. Tránh điều này