【Pythonコーディング規約】PEP 8 vs Google Style

# はじめに
Pythonのコーディング規約として有名なのは標準ライブラリのコード規約[PEP 8](https://www.python.org/dev/peps/pep-0008/)であるが、[Google Python Style Guide](https://google.github.io/styleguide/)というものがあるという。そこでGoogle StyleはPEP 8とどこが違うのかをまとめてみた。結論から言うとほとんどPEP 8と同じだったので、共通している規約（特に空行・空白関係）は割愛した。違いがあるのに網羅しきれてないところがあるかもしれないがご容赦頂きたい。

# 注
- 両者日本語訳が出ているが最新でない可能性があるので、極力英語版を参考にした
- PEP 8はpublic domain, Google Style Guideは[CC by 3.0](https://creativecommons.org/licenses/by/3.0/)


# 比較表
| 項目 | PEP8 | Google |
|:-----------|:------------|:------------|
| 複数の文を１行で書くこと       | 原則やめるべき        | `if foo: bar(foo)`は`else`を伴わなければOK。それ以外はNG。`;`も使うな。        |
| 1行の最大長    | 79文字      | 80文字       |
| 1行の最大長の例外       | チームの合意があれば99文字でも良い、いずれにしろコメント行は72文字        | import文、URL、パス名は例外         |
| 行継続の`\`         | 括弧の方が望ましいが、`with`文や`assert`等では使ってよい   | `with`文が3行以上になるときを除いて使うな           |
| docstringの使用    | non-publicメソッドでは不要、他は書け     | non-publicで短くて明らかなメソッドを除いて書け      |
| docstringのスタイル|なし（PEP257に書くべき内容が記述）|あり|
|コメントの内容|自明なことは書くな|コード自体の説明をするな。英語の文法・綴り・句読法を守れ|
|文字列の引用符`'``"`|どちらでもよい|プロジェクト内で原則どちらを使うか決めること|
|複数行文字列（docstring除く）|三重引用符を使うときは`"""`|文字列に原則`'`を使うことにしたプロジェクトでは`'''`でも良い。また他の書き方への言及あり|
|TODOコメントのスタイル|なし|あり|
|importの順序|標準ライブラリ→外部ライブラリ→ローカルライブラリ|ほぼPEP8と同じだが、辞書順であることが明記|
|1文字変数|`l`, `O`, `I`禁止|原則禁止。例外はカウンタ・イテレータの`i`等、`except`での`e`、ファイルオブジェクトの`f`
|前後に`_`を付ける命名|`_xxx`, `__xxx`, `xxx_`を使うケースに言及|非publicなら`_xxx`を使え。`__xxx`は非推奨|
|ラムダ式|変数に代入するなら`def`で書け|ワンライナー用に使え。ラムダ式部分が60-80文字超になるときはnested関数を使え。`operator`モジュールにある関数をラムダ式で書くな|
|return|使うなら全ケースでreturnしろ。returnの後には何か書け|言及無し|
|一貫性|拘り過ぎる奴は心が狭い|一貫しろ|

# 括弧で行を結合するときの書き方

```python
# PEP8でもGoogleでもOK
# 開き括弧に揃える
 foo = long_function_name(var_one, var_two,
                          var_three, var_four)
 meal = (spam,
         beans)
# PEP8でもGoogleでもOK
# hanging indent（スペース4個）
foo = long_function_name(
    var_one, var_two, var_three,
    var_four)
meal = (
    spam,
    beans)

# PEP8では許容、GoogleではNG（スペースが2個になっている）
foo = long_function_name(
  var_one, var_two,
  var_three, var_four)

# PEP8では言及なし、GoogleではOK
foo = {
    long_dictionary_key: value1 +
                         value2,
    ...
}
foo = {
    long_dictionary_key:
        long_dictionary_value,
        ...
}

# PEP8では言及無し、GoogleではNG
foo = {
    long_dictionary_key:
    long_dictionary_value,
    ...
}

# PEP8ではOK、Googleでは言及無し?
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)


# PEP8ではOK、Googleでは言及無し、もしかしたらNG
my_list = [
    1, 2, 3,
    4, 5, 6,
    ]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f',
    )

# Googleはこの書き方を好んでいる気がする。PEP8でもOK。
my_list = [
    1, 2, 3,
    4, 5, 6,
]
result = some_function_that_takes_arguments(
    'a', 'b', 'c',
    'd', 'e', 'f')

```
- PEP8では2項演算子の前で改行、Googleでは言及無し
- PEP8ではif文の条件が長くなった時の記述を例示、Googleでは言及無し
- Googleでは関数アノテーションを使ったときの記法を規定、PEP8では言及無し
- 個人的にはhanging indentの方が手間が少なく、1行を有効活用できていて好き
    - しかし関数引数は開き括弧に揃える方が見やすいような気がする...

# その他、Google Style Guideのみ言及がある事柄
- `class`定義文と最初のメソッドの間は１行空けろ
- `if __name__ == '__main__'`を使いましょう
- 関数が40行を超えたら分割を検討しましょう
- 2つの文字列の連結は`+`を使う。それ以上に連結するときは`%`, `str.format()`, `f-string`, `str.join()`を使う。
- `map()`と`filter()`を組み合わせるな
- `with`文がちょうど2行になるときはネストしろ、`\`使うな
- シェバンは書かなくてよい。直接実行しないファイルに書くのは無意味。
- 無駄な`()`は書くな。タプルを明示する`()`は書こう。
- 内包表記・ジェネレータ式で`for`文を2個以上、または制御文を2個以上使うな
- `@staticmethod`は原則使わずに、モジュールレベル関数にしよう
- `@classmethod`は名前付きコンストラクタとして使うメソッドか、クラスのグローバル状態を変更するメソッドに使おう
- デフォルト引数の定義でミュータブルを使うな
- グローバル変数は避けて、定数を使おう
- type annotationの書き方

# 感想
Googleよ、PEP 8と同じところは同じって書いてくれよ全部読むの大変だったorz。docstringやtype annotationの書き方を結構詳しく決めているところは良かった。