Trình cài đặt quá tải python

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ày

2. 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ạn

Loạ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
24

Nế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
27

Có 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ụng

2. 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
    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    35 để nhập các gói và mô-đun
  • 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
    
    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ố
  • 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
    
    39 nếu hai mô-đun có tên
    def 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ếu
    def 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ếu
    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à một tên dài bất tiện
  • Chỉ 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
    
    43 khi
    def 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 cho
    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    46]

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ư sau

from 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ã nên 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
49

2. 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

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    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 thông qua số âm nhưng yêu cầu số dương]. Không sử dụng 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
    
    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ụ

    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

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    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]

  • Không bao giờ sử dụng câu lệnh bắt tất cả

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    59 hoặc bắt
    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    60 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
    
    61, trừ khi bạn

    • 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à

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    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ắt

  • Giảm thiểu số lượng mã trong một khối

    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. Phần thân của
    def 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ối
    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 ẩn một lỗi thực sự

  • Sử dụng 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
    
    68 để thực thi mã cho dù có hay không một ngoại lệ được đưa ra trong khối
    def 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 tin

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ưới

2. 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ệm

2. 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
77

2. 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ơ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']

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
0

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
1

2. 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 sạch

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
77

2. 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
85

2. 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
86

2. 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. Each portion must fit on one line. true-expression, if-expression, else-expression. 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
2

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
3

2. 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ứ hai

2. 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
4

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
5

2. 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 một thuộc tính để lấy và đặt mộ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ột

Kế 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 boolean

2. 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

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    96 [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
    
    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 boolean

  • Không bao giờ so sánh một biến boolean 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
    
    92 bằng cách sử dụng
    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    01. Sử dụng
    from 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ệt
    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    92 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
    
    98 thì hãy xâu chuỗi các biểu thức, chẳng hạn như
    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    05

  • Đố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 đó,

    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    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ới
    from 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 ứng

  • 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ý

    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ành 0]. Bạn có thể so sánh một giá trị được biết là một số nguyên [và không phải là kết quả của
    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    11] với số nguyên 0

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    6

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    7

  • Lưu ý rằng

    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    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à true

  • 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

    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    14 khi kiểm tra tính không của một
    from 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]

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
8

2. 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
9

Vì 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]
19

2. 16. 4 Quyết định

Được rồi để sử dụng

2. 17 Trình trang trí chức năng 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]
21

2. 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ày

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
0

tương đương với

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
1

2. 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ợp

Trì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ô-đun

Chỉ 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 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 quy trình

2. 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ơn

2. 19 Tính năng nguồn

Tránh các tính năng này

2. 19. 1 Định nghĩa

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. một số cách sử dụng của

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
32], sửa đổi bên trong hệ thống, phương pháp
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
33 thực hiện dọn dẹp tùy chỉnh, v.v.

2. 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

Tránh các tính năng này trong mã của bạn

Các mô-đun và lớp thư viện tiêu chuẩn sử dụng nội bộ các tính năng này đều được phép sử dụng [ví dụ:

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 và
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
36]

2. 20 con trăn hiện đại. từ __future__ nhập khẩu

Các thay đổi ngữ nghĩa của phiên bản ngôn ngữ mới có thể được kiểm soát sau quá trình nhập đặc biệt trong tương lai để kích hoạt chúng trên cơ sở từng tệp trong thời gian chạy trước đó

2. 20. 1 Định nghĩa

Có thể bật một số tính năng hiện đại hơn thông qua câu lệnh

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
37 cho phép sử dụng sớm các tính năng từ các phiên bản Python dự kiến ​​trong tương lai

2. 20. 2 Ưu điểm

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. The need for this is more common in projects supporting an extremely wide variety of environments

2. 20. 4 Decision

from __future__ imports

Use 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 lines

In 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

For more information read the Python future statement definitions documentation

Please don’t remove these imports until you are confident the code is only ever used in a sufficiently modern environment. Even if you do not currently use the feature a specific future import enables in your code today, keeping it in place in the file prevents later modifications of the code from inadvertently depending on the older behavior

Use other

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
40 import statements as you see fit

2. 21 Type Annotated Code

You can annotate Python code with type hints according to PEP-484, and type-check the code at build time with a type checking tool like pytype

Type annotations can be in the source or in a . Whenever possible, annotations should be in the source. Use pyi files for third-party or extension modules

2. 21. 1 Definition

Type annotations [or “type hints”] are for function or method arguments and return values

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
3

You can also declare the type of a variable using similar PEP-526 syntax

2. 21. 2 Pros

Type annotations improve the readability and maintainability of your code. The type checker will convert many runtime errors to build-time errors, and reduce your ability to use

2. 21. 3 Cons

You will have to keep the type declarations up to date. You might see type errors that you think are valid code. Use of a type checker may reduce your ability to use

2. 21. 4 Decision

You are strongly encouraged to enable Python type analysis when updating code. When adding or modifying public APIs, include type annotations and enable checking via pytype in the build system. As static analysis is relatively new to Python, we acknowledge that undesired side-effects [such as wrongly inferred types] may prevent adoption by some projects. In those situations, authors are encouraged to add a comment with a TODO or link to a bug describing the issue[s] currently preventing type annotation adoption in the BUILD file or in the code itself as appropriate

3 Python Style Rules

3. 1 Semicolons

Do not terminate your lines with semicolons, and do not use semicolons to put two statements on the same line

3. 2 Line length

Maximum line length is 80 characters

Explicit exceptions to the 80 character limit

  • Long import statements
  • URLs, pathnames, or long flags in comments
  • Long string module level constants not containing whitespace that would be inconvenient to split across lines such as URLs or pathnames
    • Pylint disable comments. [e. g.
      from sound.effects import echo
      ...
      echo.EchoFilter[input, output, delay=0.7, atten=4]
      
      41]

Do not use backslash line continuation except for

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 statements requiring three or more context managers

Make use of Python’s . If necessary, you can add an extra pair of parentheses around an expression

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
4

When a literal string won’t fit on a single line, use parentheses for implicit line joining

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
5

Within comments, put long URLs on their own line if necessary

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
6

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
7

It is permissible to use backslash continuation when defining a

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 statement with three or more context managers. For two context managers, use a nested
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
42 statement

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
8

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
9

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
0

Make note of the indentation of the elements in the line continuation examples above; see the section for explanation

In all other cases where a line exceeds 80 characters, and the yapf auto-formatter does not help bring the line below the limit, the line is allowed to exceed this maximum. 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 Parentheses

Use parentheses sparingly

It is fine, though not required, to use parentheses around tuples. Do not use them in return statements or conditional statements unless using parentheses for implied line continuation or to indicate a tuple

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
1

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
2

3. 4 Indentation

Indent your code blocks with 4 spaces

Never use tabs. Implied line continuation should align wrapped elements vertically [see ], or use a hanging 4-space indent. Closing [round, square or curly] brackets can be placed at the end of the expression, or on separate lines, but then should be indented the same as the line with the corresponding opening bracket

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

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
4

3. 4. 1 Trailing commas in sequences of items?

Trailing commas in sequences of items are recommended only when the closing container token

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, or
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
47 does not appear on the same line as the final element. The presence of a trailing comma is also used as a hint to our Python code auto-formatter YAPF to direct it to auto-format the container of items to one item per line when the
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
48 after the final element is present

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
5

3. 5 Blank Lines

Two blank lines between top-level definitions, be they function or class definitions. One blank line between method definitions and between the docstring of a

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
49 and the first method. No blank line following a
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
50 line. Use single blank lines as you judge appropriate within functions or methods

Blank lines need not be anchored to the definition. For example, related comments immediately preceding function, class, and method definitions can make sense. Consider if your comment might be more useful as part of the docstring

3. 6 Whitespace

Follow standard typographic rules for the use of spaces around punctuation

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[...]
6

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
7

No 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[...]
8

Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
9

No 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[...]
0

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
1

No 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 value

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
2

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
3

Don’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[...]
4

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
5

3. 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-394

This 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 below

3. 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[...]
6

3. 8. 2. 1 Test modules

Module-level docstrings for test files are not required. They should be included only when there is additional information that can be provided

Các ví dụ bao gồm một số chi tiết cụ thể về cách chạy thử nghiệm, giải thích về mẫu thiết lập bất thường, sự phụ thuộc vào môi trường bên ngoài, v.v.

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
7

Docstrings that do not provide any new information should not be used

3. 8. 3 Functions and Methods

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
  • kích thước không tầm thường
  • logic không rõ ràng

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 method

Certain 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 accepts
from 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[...]
8

Similarly, this variation on

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
86 with a line break is also allowed

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
9

3. 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 section

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
0

All 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. The class docstring should not repeat unnecessary information, such as that the class is a class

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
1

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
2

3. 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

To improve legibility, these comments should start at least 2 spaces away from the code with the comment character

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
65, followed by at least one space before the text of the comment itself

On the other hand, never describe the code. 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
4

3. 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. Proper punctuation, spelling, and grammar help with that goal

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]
54

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
5

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
6

Avoid 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 complexity

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
7

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
8

Be 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 string

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
9

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
0

Thích

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
74 cho các chuỗi nhiều dòng hơn là
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 regardless

Multi-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
1

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
2

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
3

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
4

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
5

3. 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. Some logging implementations collect the unexpanded pattern-string as a queryable field. 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
6

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
7

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
8

3. 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 guidelines

  1. The message needs to precisely match the actual error condition

  2. Interpolated pieces need to always be clearly identifiable as such

  3. 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
9

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
0

3. 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
    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    33 method. Different Python implementations use different memory management techniques, such as delayed garbage collection, which may increase the object’s lifetime arbitrarily and indefinitely
  • 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
1

For 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[...]
11

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
2

In 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 perfect

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 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 do

The 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 given

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
3

If 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 comprehend

3. 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
4

Imports are always put at the top of the file, just after any module comments and docstrings and before module globals and constants. Imports should be grouped from most generic to least generic

  1. Python future import statements. For example

    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
    
    5

    See for more information about those

  2. Python standard library imports. For example

  3. third-party module or package imports. Ví dụ

  4. Code repository sub-package imports. Ví dụ

    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
    
    6

  5. Deprecated. application-specific imports that are part of the same top level sub-package as this file. For example

    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
    
    7

    You may find older Google Python Style code doing this, but it is no longer required. Mã mới được khuyến khích không bận tâm với điều này. Đơn giản chỉ cần xử lý các lần nhập gói phụ dành riêng cho ứng dụng giống như các lần nhập gói phụ khác

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 sections

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
8

3. 14 Tuyên bố

Nói chung chỉ có một tuyên bố trên mỗi dòng

Tuy nhiên, bạn chỉ có thể đặt kết quả của một bài kiểm tra trên cùng một dòng với bài kiểm tra nếu toàn bộ câu lệnh nằm trên một dòng. Đặc biệt, bạn không bao giờ có thể làm như vậy 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
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 vì
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
63 và
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
64 không thể vừa trên cùng một dòng và bạn chỉ có thể làm như vậy với
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 nếu không có
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
30

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
9

3. 15 Getters và Setters

Các hàm getter và setter [còn được gọi là bộ truy cập và bộ biến đổi] nên được sử dụng khi chúng cung cấp vai trò hoặc hành vi có ý nghĩa để nhận hoặc đặt giá trị của biến

Đặc biệt, chúng nên được sử dụng khi nhận hoặc thiết lập biến phức tạp hoặc chi phí đáng kể, hiện tại hoặc trong tương lai hợp lý

Ví dụ: nếu một cặp getters/setters chỉ đọc và ghi một thuộc tính nội bộ, thì thuộc tính nội bộ sẽ được công khai thay thế. Để so sánh, nếu việc đặt một biến có nghĩa là một số trạng thái bị vô hiệu hóa hoặc được xây dựng lại, thì đó phải là một hàm setter. Lời gọi hàm gợi ý rằng một hoạt động có khả năng không tầm thường đang xảy ra. Ngoài ra, có thể là một tùy chọn khi cần logic đơn giản hoặc tái cấu trúc để không còn cần getters và setters nữa

Getters và setters nên tuân theo các hướng dẫn, chẳng hạn như

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 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[...]
32

Nếu hành vi trong quá khứ cho phép truy cập thông qua một thuộc tính, không liên kết các hàm getter/setter mới với thuộc tính. Bất kỳ mã nào vẫn đang cố truy cập vào biến theo phương pháp cũ sẽ bị hỏng rõ ràng để chúng nhận thức được sự thay đổi về độ phức tạp

3. 16 đặt tên

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[...]
45

Tên hàm, tên biến và tên tệp phải mang tính mô tả; . Đặc biệt, không sử dụng các từ viết tắt mơ hồ hoặc không quen thuộc với người đọc bên ngoài dự án của bạn và không viết tắt bằng cách xóa các chữ cái trong một từ

Luôn sử dụng phần mở rộng tên tệp

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
67. Không bao giờ sử dụng dấu gạch ngang

3. 16. 1 Tên cần tránh

  • tên ký tự đơn, ngoại trừ các trường hợp được phép cụ thể

    • bộ đếm hoặc bộ lặp [e. g.
      Yes:
        # Reference absl.flags in code with the complete name [verbose].
        import absl.flags
        from doctor.who import jodie
      
        _FOO = absl.flags.DEFINE_string[...]
      
      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, v.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[...]
      
      51 làm định danh ngoại lệ trong câu lệnh
      Yes:
        # Reference absl.flags in code with the complete name [verbose].
        import absl.flags
        from doctor.who import jodie
      
        _FOO = absl.flags.DEFINE_string[...]
      
      52
    • Yes:
        # Reference absl.flags in code with the complete name [verbose].
        import absl.flags
        from doctor.who import jodie
      
        _FOO = absl.flags.DEFINE_string[...]
      
      53 dưới dạng xử lý tệp trong câu lệnh
      from sound.effects import echo
      ...
      echo.EchoFilter[input, output, delay=0.7, atten=4]
      
      42
    • riêng tư không có ràng buộc [e. g.
      Yes:
        # Reference absl.flags in code with the complete name [verbose].
        import absl.flags
        from doctor.who import jodie
      
        _FOO = absl.flags.DEFINE_string[...]
      
      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]

    Xin lưu ý không lạm dụng đặt tên một ký tự. Nói chung, tính mô tả phải tỷ lệ thuận với phạm vi hiển thị của tên. Ví dụ:

    Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    47 có thể là một tên hay cho khối mã 5 dòng nhưng trong nhiều phạm vi lồng nhau, nó có thể quá mơ hồ

  • dấu gạch ngang [

    from sound.effects import echo
    ...
    echo.EchoFilter[input, output, delay=0.7, atten=4]
    
    55] trong bất kỳ tên gói/mô-đun nào

  • Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    61 tên [được đặt trước bởi Python]

  • điều khoản xúc phạm

  • những tên không cần thiết bao gồm loại biến [ví dụ:.

    Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    62]

3. 16. 2 Quy ước đặt tên

  • “Nội bộ” có nghĩa là nội bộ của một mô-đun hoặc được bảo vệ hoặc riêng tư trong một lớp

  • Đặt trước một dấu gạch dưới [

    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ó một số hỗ trợ để bảo vệ các biến và chức năng của mô-đun [linters sẽ gắn cờ quyền truy cập của thành viên được bảo vệ]

  • Việc thêm trước một dấu gạch dưới kép [

    Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    64 hay còn gọi là “dunder”] vào một biến thể hiện hoặc phương thức sẽ làm cho biến hoặc phương thức đó trở nên riêng tư đối với lớp của nó [sử dụng xáo trộn tên]; . Thích một dấu gạch dưới

  • Đặt các lớp liên quan và các chức năng cấp cao nhất cùng nhau trong một mô-đun. Không giống như Java, không cần giới hạn bản thân trong một lớp cho mỗi mô-đun

  • Sử dụng CapWords cho tên lớp, nhưng Lower_with_under. py cho tên mô-đun. Mặc dù có một số mô-đun cũ có tên là CapWords. py, điều này hiện không được khuyến khích vì thật khó hiểu khi mô-đun được đặt tên theo một lớp. [“chờ đã – tôi đã viế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[...]
    
    65 hay
    Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    66?”]

  • Dấu gạch dưới có thể xuất hiện trong các tên phương thức kém nhất bắt đầu bằ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[...]
    
    67 để phân tách các thành phần logic của tên, ngay cả khi các thành phần đó sử dụng CapWords. Một mẫu có thể là
    Yes:
      # Reference absl.flags in code with the complete name [verbose].
      import absl.flags
      from doctor.who import jodie
    
      _FOO = absl.flags.DEFINE_string[...]
    
    68; . Không có một cách chính xác nào để đặt tên cho các phương pháp thử nghiệm

3. 16. 3 Đặt tên tệp

Tên tệp Python phải có phần mở rộng

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
67 và không được chứa dấu gạch ngang [
from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
55]. Điều này cho phép chúng được nhập và kiểm tra. Nếu bạn muốn một tệp thực thi có thể truy cập được mà không cần tiện ích mở rộng, hãy sử dụng liên kết tượng trưng hoặc trình bao bọc bash đơn giản có chứ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[...]
72

3. 16. 4 Nguyên tắc rút ra từ Khuyến nghị của Guido

TypePublicInternalPackages
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73Modules
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
75Classes
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
76
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
77Exceptions
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
76Functions
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
79
Yes:
  # 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 Constants
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
81
Yes:
  # 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 Variables
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
75Instance Variables
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73
Yes:
  # 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 Names
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
79
Yes:
  # 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 Parameters
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73Local Variables
Yes:
  # Reference absl.flags in code with the complete name [verbose].
  import absl.flags
  from doctor.who import jodie

  _FOO = absl.flags.DEFINE_string[...]
73

3. 16. 5 Ký hiệu toán học

Đối với mã nặng về mặt toán học, các tên biến ngắn sẽ vi phạm hướng dẫn kiểu được ưu tiên hơn khi chúng khớp với ký hiệu đã thiết lập trong tài liệu tham khảo hoặc thuật toán. Khi làm như vậy, hãy tham khảo nguồn của tất cả các quy ước đặt tên trong một nhận xét hoặc chuỗi tài liệu hoặc, nếu nguồn không thể truy cập được, hãy ghi lại rõ ràng các quy ước đặt tên. Ưu tiên

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 tuân thủ PEP8 cho các API công khai, có nhiều khả năng gặp phải ngoài ngữ cảnh hơn

3. 17 chính

Trong Python,

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
25 cũng như các bài kiểm tra đơn vị yêu cầu các mô-đun có thể nhập được. Nếu một tệp được dùng làm tệp thực thi, thì chức năng chính của nó phải ở hàm
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 và mã của bạn phải luôn kiểm tra
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 trước khi thực thi chương trình chính của bạn, để nó không được thực thi khi mô-đun được nhập

Khi sử dụng absl, hãy sử dụ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[...]
95

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']
0

Nếu không, hãy sử dụ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']
1

Tất cả mã ở cấp cao nhất sẽ được thực thi khi mô-đun được nhập. Cẩn thận không gọi hàm, tạo đối tượng hoặc thực hiện các thao tác khác không được thực hiện khi tệp đang được ____32_______25ed

3. 18 Chiều dài chức năng

Thích các chức năng nhỏ và tập trung

Chúng tôi nhận ra rằng các hàm dài đôi khi phù hợp, vì vậy không có giới hạn cứng nào được đặt cho độ dài của hàm. Nếu một hàm vượt quá khoảng 40 dòng, hãy nghĩ xem có thể chia nhỏ hàm đó mà không làm hại cấu trúc của chương trình hay không

Ngay cả khi chức năng lâu dài của bạn hiện đang hoạt động hoàn hảo, ai đó sửa đổi nó sau vài tháng có thể thêm hành vi mới. Điều này có thể dẫn đến các lỗi khó tìm. Giữ chức năng của bạn ngắn gọn và đơn giản giúp người khác đọc và sửa đổi mã của bạn dễ dàng hơn

Bạn có thể tìm thấy các hàm dài và phức tạp khi làm việc với một số mã. Đừng bị đe dọa bằng cách sửa đổi mã hiện có. nếu làm việc với một chức năng như vậy tỏ ra khó khăn, bạn thấy rằng các lỗi khó gỡ lỗi hoặc bạn muốn sử dụng một phần của nó trong nhiều ngữ cảnh khác nhau, hãy cân nhắc chia chức năng thành các phần nhỏ hơn và dễ quản lý hơn

3. 19 Chú thích Loại

3. 19. 1 Quy tắc chung

  • Làm quen với PEP-484

  • Trong các phương thức, chỉ chú 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
    
    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 nếu cần thiết cho thông tin loại phù hợp. e. g. ,

    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']
    
    2

  • Tương tự, đừng cảm thấy bắt buộc phải chú thích giá trị trả về củ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[...]
    
    99 [trong đó
    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à tùy chọn hợp lệ duy nhất]

  • Nếu không thể biểu thị bất kỳ biến nào khác hoặc kiểu trả về, 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[...]
    
    01

  • Bạn không bắt buộc phải chú thích tất cả các chức năng trong một mô-đun

    • Ít nhất hãy chú thích các API công khai của bạn
    • Sử dụng phán đoán để đạt được sự cân bằng tốt giữa một mặt là an toàn và rõ ràng, mặt khác là linh hoạt
    • Chú thích mã dễ bị lỗi liên quan đến loại [lỗi trước đó hoặc độ phức tạp]
    • Chú thích mã khó hiểu
    • Chú thích mã khi nó trở nên ổn định từ góc độ loại. Trong nhiều trường hợp, bạn có thể chú thích tất cả các chức năng trong mã trưởng thành mà không mất quá nhiều tính linh hoạt

3. 19. Ngắt 2 dòng

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']
3

Luô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']
4

If the combination of the function name, the last parameter, and the return type is too long, indent by 4 in a new line. 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]
50

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']
5

Optionally, the return type may be put on the same line as the last parameter

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']
6

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
18 allows you to move the closing parenthesis to a new line and align with the opening one, but this is less readable

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']
7

As in the examples above, prefer not to break types. However, sometimes they are too long to be on a single line [try to keep sub-types unbroken]

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']
8

If a single name and type is too long, consider using an for the type. The last resort is to break after the colon and indent by 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']
9

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]
0

3. 19. 3 Forward Declarations

If you need to use a class name [from the same module] that is not yet defined – for example, if you need the class name inside the declaration of that class, or if you use a class that is defined later in the code – either 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[...]
04 or use a string for the class name

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]
1

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

3. 19. 4 Default Values

As per , use spaces around the

from sound.effects import echo
...
echo.EchoFilter[input, output, delay=0.7, atten=4]
51 only for arguments that have both a type annotation and a default value

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]
3

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]
4

3. 19. 5 NoneType

In the Python type system,

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 is a “first class” type, and for typing purposes,
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
98 is an alias for
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. If an argument can be
def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
98, it has to be declared. You can 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[...]
10, but if there is only one other type, 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[...]
11

Use explicit

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 instead of implicit
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. Earlier versions of PEP 484 allowed
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 to be interpreted as
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, but that is no longer the preferred behavior

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]
5

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]
6

3. 19. 6 Type Aliases

You can declare aliases of complex types. The name of an alias should be CapWorded. Nếu bí danh chỉ được sử dụng trong mô-đun này, thì bí danh đó phải là _Private

For example, if the name of the module together with the name of the type is too long

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]
7

Other examples are complex nested types and multiple return variables from a function [as a tuple]

3. 19. 7 kiểu phớt lờ

You can disable type checking on a line with the special comment

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
16

Yes:
  # Reference flags in code with just the module name [common].
  from absl import flags
  from doctor.who import jodie

  _FOO = flags.DEFINE_string[...]
17 has a disable option for specific errors [similar to lint]

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]
8

3. 19. 8 Typing Variables

If an internal variable has a type that is hard or impossible to infer, specify its type with an annotated assignment - use a colon and type between the variable name and value [the same as is done with function arguments that have a default value]

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]
9

Mặ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òng

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
00

3. 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
01

3. 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úng

Thí dụ

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
02

Mộ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
03

Biế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ại

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
04

TypeVar 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
05

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
06

3. 19. 11 loại chuỗi

Không 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[...]
24 trong mã mới. Nó chỉ tương thích với Python 2/3

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[...]
23 cho dữ liệu chuỗi/văn bản. Đối với mã liên quan đến dữ liệu nhị phân, 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[...]
22

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
07

Nếu tất cả các kiểu chuỗi của một hàm luôn giống nhau, chẳng hạn nếu kiểu trả về giống với kiểu đối số trong đoạn mã trên, hãy sử dụng

3. 19. 12 Nhập khẩu để gõ

Đối với các ký hiệu 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 được sử dụng để hỗ trợ phân tích tĩnh và kiểm tra loại, hãy luôn nhập chính ký hiệu đó. Điều này giữ cho các chú thích phổ biến ngắn gọn hơn và phù hợp với các cách gõ được sử dụng trên khắp thế giới. 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. Bá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
08

Cho rằng cách nhập này thêm các mục vào không gian tên cục bộ, các tên trong

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 hoặc
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 phải được xử lý tương tự như các từ khóa và không được xác định trong mã Python của bạn, được nhập hay không. Nếu có sự xung đột giữa một loại và một tên hiện có trong một mô-đun, hãy nhập nó bằng cách 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[...]
33

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
09

Ưu tiên sử dụng các loại tích hợp làm chú thích nếu có. Python hỗ trợ các chú thích loại bằng cách sử dụng các loại vùng chứa tham số qua PEP-585, được giới thiệu trong 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
10

GHI CHÚ. 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[...]
21

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
11

3. 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 bình 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

    def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
        del beans, eggs  # Unused by vikings.
        return spam + spam + spam
    
    12

3. 19. 14 phụ thuộc tuần hoàn

Các phụ thuộc tròn gây ra bởi việc gõ là mã có mùi. 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òng

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
13

3. 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
14

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
15

Nế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ơn

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
16

def viking_cafe_order[spam: str, beans: str, eggs: Optional[str] = None] -> str:
    del beans, eggs  # Unused by vikings.
    return spam + spam + spam
17

4 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

Chủ Đề