Follow Google Python Style Guide,下方列出幾點我覺得重要的。

Naming

  1. 使用 Snake Case 命名
  2. Internal 表示僅 module 內可用,或是 private
  3. 下劃線 (_) 開頭表示 module variable,或函數是 protected的 (使用import * from時不會包含)
  4. 雙下劃線 (__) 開頭的 instance variable 或 method 表示類內私有.

Comments

Functions and Methods

  1. Args
  2. Returns
  3. Raises
def fetch_smalltable_rows(
    table_handle: smalltable.Table,
    keys: Sequence[bytes | str],
    require_all_keys: bool = False,【
) -> Mapping[bytes, tuple[str, ...]]:
    """Fetches rows from a Smalltable.

    Retrieves rows pertaining to the given keys from the Table instance
    represented by table_handle.  String keys will be UTF-8 encoded.

    Args:
        table_handle: An open smalltable.Table instance.
        keys: A sequence of strings representing the key of each table
          row to fetch.  String keys will be UTF-8 encoded.
        require_all_keys: If True only rows with values set for all keys will be
          returned.

    Returns:
        A dict mapping keys to the corresponding table row data
        fetched. Each row is represented as a tuple of strings. For
        example:

        {b'Serak': ('Rigel VII', 'Preparer'),
         b'Zim': ('Irk', 'Invader'),
         b'Lrrr': ('Omicron Persei 8', 'Emperor')}

        Returned keys are always bytes.  If a key from the keys argument is
        missing from the dictionary, then that row was not found in the
        table (and require_all_keys must have been False).

    Raises:
        IOError: An error occurred accessing the smalltable.
    """

Classes

class SampleClass:
    """Summary of class here.

    Longer class information...
    Longer class information...

    Attributes:
        likes_spam: A boolean indicating if we like SPAM or not.
        eggs: An integer count of the eggs we have laid.
    """

    def __init__(self, likes_spam: bool = False):
        """Initializes the instance based on spam preference.

        Args:
          likes_spam: Defines if instance exhibits this preference.
        """
        self.likes_spam = likes_spam
        self.eggs = 0

    def public_method(self):
        """Performs operation blah."""

Block and Inline Comments

# We use a weighted dictionary search to find out where i is in
# the array.  We extrapolate position based on the largest num
# in the array and the array size and then do binary search to
# get the exact number.

if i & (i-1) == 0:  # True if i is 0 or a power of 2.

Imports formatting

Yes: from collections.abc import Mapping, Sequence
     import os
     import sys
     from typing import Any, NewType


No:  import os, sys

導入需要放在文件頂部,導入按照下方順序。各分組中,需要根據字母大小排序,忽略大小寫

  1. 標準庫導入
  2. 第三方庫導入
  3. 應用程序指定導入
import collections
import queue
import sys
from absl import app
from absl import flags
import bs4
import cryptography
import tensorflow as tf
from book.genres import scifi
from myproject.backend import huxley
from myproject.backend.hgwells import time_machine
from myproject.backend.state_machine import main_loop
from otherproject.ai import body
from otherproject.ai import mind
from otherproject.ai import soul
# Older style code may have these imports down here instead:
#from myproject.backend.hgwells import time_machine
#from myproject.backend.state_machine import main_loop

Tools

isort

自動排序 import 程式行令其符合 PEP8 風格。

"isort.args": [
    "--src=${workspaceFolder}",
    "--line-length=120",
],

存檔時自動格式化

"[python]": {
    "editor.codeActionsOnSave": {
        "source.organizeImports": true
    },
    ...
},

flake8

為 Python Linter,檢查程式是否有語法錯誤並提示、檢查程式是否符合 PEP 8 風格並提示。VS Code 設定 Flake8 只有幾個重要的環節,依序如下:

開啟 Python Linting:Python › Linting: Enabled
開啟 Flake8 Linting:Python › Linting: Flake8 Enabled
設定 Flake8 Args(非必要):Python › Linting: Flake8 Args

或是直接在 VS Code 的settings.json 加入以下內容

"python.linting.enabled": true, // 預設值即為 true
"python.linting.flake8Enabled": true,
"python.linting.flake8Args": [
  "--max-line-length=120",
  "--ignore=E402,F841,F401,E302,E305",
]

yapf

Python formatter,主要是為了讓 Python 程式碼可以最大限度遵守 PEP 8 及一般風格規範。settings.json設定如下:

"python.formatting.provider": "yapf",
"python.formatting.yapfArgs": [
    "--style={column_limit=120}"
  ],
"editor.formatOnSave": true, // 不支援 afterDelay 自動存檔

setting.json

這是我的 vscode 設定

"[python]": {
        "editor.codeActionsOnSave": {
            "source.organizeImports": true
        },
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "eeyore.yapf",
    },
    "yapf.args": [
        "--style", "{based_on_style: yapf, column_limit=120,INDENT_WIDTH=4,SPLIT_BEFORE_DOT=false,SPLIT_ALL_TOP_LEVEL_COMMA_SEPARATED_VALUES=true,spaces_before_comment='15, 20'}"
    ],

    "isort.args": [
        "--src=${workspaceFolder}",
        "--line-length=120",
    ],
    "flake8.args":[
        "--max-line-length=120",
        "--ignore=E402,F841,F401,E302,E305,W503,W292,E501,F841",
    ],