Pythonのコーディングスタイル入門

スクリプト言語としてのPythonは非常にシンプルでコンパクトです。他の言語と比較して、適切なPythonコードを書くために内在化するキーワードの数は比較的少なくて済みます。さらに、コードのシンプルさと読みやすさの両方が好まれ、これはPythonが自負していることです。この2つの目標を達成するためには、言語固有のガイドラインに従うことが有効です。

この記事では、よりPythonicなプログラミングの方法を表す有効なコードを書くために、上記のガイドラインに焦点を当てます。これは実用的な使い方に焦点を当てたガイドラインの抜粋であり、さらなるガイドラインはThe Hitchhiker’s Guide to PythonとPEP8 Style Guideで読むことができます。

アメリカのPython開発者であるTim Petersは、「Zen of Python」の中で言語の原則をユーモラスにまとめています。これらのルールは、言語の主なターゲットとスタイルで構成されています。これらのルールが、開発者としての方向性を定めるのに役立つことを願っています。

Pythonの禅



Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than right now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
    --Tim Peters


一般的なプログラミングのガイドライン

Python の Zen に従って、コードの読みやすさは重要です。例えば、一貫したインデント、特定の行の長さ、1行に1つの文のみ、コードの断片を暗黙の方法ではなく、明示的な方法で定式化することなどです。以下、これらのルールを順を追って説明します。

インデント

クラス、関数(またはメソッド)、ループ、条件、リストでは、インデントが必要です。タブとスペースのどちらを使っても構いませんが、同じスクリプトの中で両方を組み合わせてはいけません。Python 3では、スペースが推奨されるインデント方法であり、より具体的には4つのスペースが望ましいとされています。例として、リストは以下のようにこの2つの方法のどちらかで定義することが推奨されています。

リストの書き方

# version 1
numbers = [
    1, 2, 3,
    4, 5, 6
    ]


# version 2
numbers = [
    1, 2, 3,
    4, 5, 6
]


PEP8で指摘されているように、閉じ括弧は「バージョン1」のようにリストの最終行の空白でない最初の文字の下に並べるか、「バージョン2」のようにリストを開始する行の最初の文字の下に並べるかのどちらかになります。

スペースを使用すると、インデントレベルごとに同じ数のスペースで作業する必要があります。次の例は、タブレータと各行に異なる数のスペースを混在させる、あなたのコードをどのように書いてはいけないかを示しています。

悪い例

def draw_point(x, y):
  """draws a point at position x,y"""

    if (x > 0):
      set_point(x, y)
  return


コードブロックを適切にインデントするために、次の例ではインデントレベルごとに4つのスペースを使用しています。

良い例

def draw_point(x, y):
    """draws a point at position x,y"""


if (x > 0):
        set_point(x, y)
    return


1行に1つの明細書

上の例は、コードを書く際のもうひとつの重要なルール、「1行に1つのステートメントしか使わない」に従っています。しかし、Python言語では、以下のようにセミコロンで区切った複数のステートメントを1行に書くことができます。

悪い

print ("Berlin"); print ("Cape Town")


if x == 1: print ("Amsterdam")


より分かりやすくするために、次のようにコードを書いてください。

良い

print ("Berlin")
print ("Cape Town")


if x == 1:
    print ("Amsterdam")


これは、Pythonのモジュールを使う場合にも当てはまります。多くのプログラミングの例では、以下のように1行で2つ以上のモジュールがインポートされています。

バッドプラクティス

import sys, os


1行に1つのモジュールをインポートする方がずっとよいです。

グッドプラクティス

良い方法

importステートメントはファイルの先頭、著作権情報、docstring の後に置きます。さらに、import`文はPythonライブラリの標準モジュール、関連するサードパーティモジュール、そして最後にライブラリ固有のimportにグループ化するのが一般的です。空白行やコメントを挿入することで、コードの可読性や理解を深めることができます。

外部モジュールのインポート

import sys
import os


行の長さ

1行は79文字以内、docstringやコメントは72文字以内とします。コードの行は、以下のようにバックスラッシュ(“)を使って折り返すことができます。

改行を含むコード

# use operating-system specific routines
import os


# use regular expressions routines
import re


# use SAX XML library/parser
from xml.sax import make_parser, handler
...


明示的なコードと暗黙的なコード

スクリプト言語としての Python は、コード全体に「トリック」を使うことができるほど柔軟です。しかし、あなたのコードは何度も他の開発者に読まれることを考慮する必要があります。読みやすさを向上させるためには、ワンライナーや「トリック」のような暗黙の前提ではなく、明示的にコードを記述するのがよいでしょう。

以下の例では、関数 calculation() は 2 つの値 xyargs という 1 つのパラメータに隠しています。この書き方では、呼び出し側が必要に応じて、これらの値より多いまたは少ない値を関数に渡すこともできますが、一見すると明らかではありません。

悪い点

with open('/path/to/some/file/you/want/to/read') as file_1, 
     open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())


より明確にするために、代わりにこのように書くことをお勧めします。

良い

def calculation(*args):
    """calculation of the total"""


x, y = args
    return (x+y)


print(calculation(3, 4))


命名規則

モジュール、クラス、メソッド/関数、変数の命名には、いくつかのバリエーションがあります。これには、小文字と大文字の使い分け、アンダースコアの有無、大文字と小文字の使い分け、それらの混在などがあります。開発者が非常に多様であるため、これらのスタイルをすべて見つけることができ、モジュール間の一貫性はほとんどありません。

ネーミングスタイルのバリエーション

def calculation(x,y):
    """calculation of the total"""


total = x + y
    return (total)


print(calculation(3, 4))


どのスタイルを使用するかは、あなた次第です。繰り返しになりますが、一貫性を保ち、コード全体で同じスタイルを使用するようにしましょう。PEP8では、主に次のような規則が適用されます。

  • 識別子の名前はASCII互換でなければならない。
  • モジュールはすべて小文字の短い名前でなければならない。
  • クラスは大文字の単語規則に従う
  • 例外は大文字の単語規則に従います。また、エラーを参照する場合は Error という接尾辞をつけることが期待されます。
  • 定数は大文字で書かれます。

詳細はPEP8標準を参照してください。

また、Pythonで変数を命名する際には、「小文字とアンダースコア」のアプローチを使うことがより「Pythonic」であると考えられていることを指摘しておきますが、どのようなアプローチも許可されているわけではありません。

コードスタイルの検証

ガイドラインは、ある条件に従ったコードを実現するための素晴らしいものです。プログラマーとして、可能な限りガイドラインに従うようにしたいものです。自動化されたツールは、コードの検証を手助けしてくれる素晴らしいものです。

前述の通り、ガイドラインはPEP8で記述されています。そのため、Python言語には、あなたのコードをガイドラインに照らしてチェックするのに役立つ、対応するコマンドラインツールが含まれています。元々は pep8 として知られていたこのコードチェッカーは、2016年に pycodestyle に改名されました。Python Code Quality Authorityによってメンテナンスされており、ソースコードアナライザーのpylintやpyflakes、複雑性チェックツールのmccabe、docstringチェックツールのpydocstyleなど、多くのツールに属しています。

pycodestyle` は Python コードを解析し、インデントエラー、不要な空白行、スペースの代わりにタビュレータを使用するなどの違反を報告します。次の例は、典型的なエラーと警告を含むサンプル出力です。

shoppingcart = []  # lowercase
shopping_cart = [] # lowercase with underscores
SHOPPINGCART = []  # uppercase
SHOPPING_CART = [] # uppercase with underscores
ShoppingCart = []  # capitalized words
shoppingCart = []  # mixed style


Debian GNU/Linux では、このツールは python-pycodestyle (Python 2.x 用) と python3-pycodestyle (Python 3.x 用) というパッケージとして提供されています。どちらも、例えば以下のような便利なパラメータが付属しています。

  • --first: 各エラーの最初の発生箇所を表示します(上図のように)。出力には、エラーが検出されたファイル、行番号、カラムが表示されます。
  • --show-source: 各エラーに対応するソースコードを表示します。
$ pycodestyle --first stack.py
stack.py:3:1: E265 block comment should start with '# '
stack.py:12:1: E302 expected 2 blank lines, found 1
stack.py:13:1: W191 indentation contains tabs


  • --statistics: エラーと警告をカウントする。以下の例では、 pycodestyle は 2 つのエラー (E265 と E302) と 30 個の警告 (W191) を検出しました。
$ pycodestyle --show-source stack.py
stack.py:3:1: E265 block comment should start with '# '
#o
^
stack.py:12:1: E302 expected 2 blank lines, found 1
class Stack:
^
stack.py:13:1: W191 indentation contains tabs
    def __init__(self):
^
...


同じツールはオンラインでも利用可能です。コードをコピーしてツールに貼り付けるだけで、検証結果を見ることができます。

結論

適切なPythonのコードを書くことは必ずしも簡単ではありません。しかし幸運なことに、あなたのコードがこれらのガイドラインを満たしていることを確認するためのコマンドラインツールと同様に、助けとなるガイドラインが存在します。様々なリソースを利用することで、とても簡単になります 🙂

謝辞

Zoleka Hatitongweのサポートに感謝する。

タイトルとURLをコピーしました