PEP 8で美しいPythonコードを書く方法

PEP 8で美しいPythonコードを書く方法

PEP 8は、PEP8またはPEP-8と綴られることもありますが、Pythonコードの記述方法に関するガイドラインとベストプラクティスを提供するドキュメントです。 2001年にGuido van Rossum、Barry Warsaw、およびNick Coghlanによって書かれました。 PEP 8の主な焦点は、Pythonコードの可読性と一貫性を改善することです。

PEPはPython Enhancement Proposalの略で、いくつかあります。 PEPは、Python向けに提案された新しい機能を説明するドキュメントであり、コミュニティ向けにPythonのデザインやスタイルなどの側面を文書化したものです。

このチュートリアルでは、PEP 8で規定されている主要なガイドラインの概要を説明します。 初心者から中級のプログラマーを対象としているため、最も高度なトピックのいくつかは取り上げていません。 これらについては、PEP 8のドキュメント全体を読むことで学ぶことができます。

By the end of this tutorial, you’ll be able to

  • PEP 8に準拠するPythonコードを書く

  • PEP 8に記載されているガイドラインの背後にある理由を理解する

  • 開発環境をセットアップして、PEP 8準拠のPythonコードの記述を開始できるようにします

Free Bonus:5 Thoughts On Python Masteryは、Python開発者向けの無料コースで、Pythonスキルを次のレベルに引き上げるために必要なロードマップと考え方を示しています。

PEP 8が必要な理由

「読みやすさは重要です。」

The Zen of Python

PEP 8は、Pythonコードの可読性を向上させるために存在します。 しかし、なぜ読みやすさがそれほど重要なのでしょうか? 読み取り可能なコードを記述することがPython言語の基本原則の1つであるのはなぜですか?

Guido van Rossumが言ったように、「コードは書かれているよりもずっと頻繁に読まれます。」ユーザー認証を処理するためのコードを書くのに数分、または丸1日かかることがあります。 一度書いたら、二度と書きません。 ただし、必ずもう一度読む必要があります。 そのコードは、現在取り組んでいるプロジェクトの一部である可能性があります。 そのファイルに戻るたびに、そのコードが何をするのか、なぜコードを書いたのかを覚えておく必要があるため、読みやすさが重要になります。

Pythonを初めて使用する場合、コードを書いてから数日または数週間後にコードが何をするかを覚えるのは困難です。 PEP 8に従うと、変数に適切な名前を付けたことを確認できます。 コード内の論理的な手順を簡単に実行できるように、十分な空白を追加したことがわかります。 また、コードに適切にコメントすることもできます。 これはすべて、コードが読みやすく、簡単にアクセスできることを意味します。 初心者として、PEP 8のルールに従うことで、Pythonをより快適に学ぶことができます。

開発の仕事を探している場合は、PEP 8に従うことが特に重要です。 明確で読みやすいコードを書くことは、プロ意識を示しています。 コードをうまく構成する方法を理解していることを雇用者に伝えます。

Pythonコードの作成経験が豊富な場合は、他の人と協力する必要があるかもしれません。 ここに読み取り可能なコードを書くことが重要です。 あなたに会ったことがないか、あなたのコーディングスタイルを見たことがない人は、あなたのコードを読んで理解する必要があります。 ガイドラインを遵守し、認識しておくと、他の人がコードを読みやすくなります。

命名規則

「明示的は暗黙的よりも優れています。」

The Zen of Python

Pythonコードを作成するときは、変数、関数、クラス、パッケージなど、多くの名前を付ける必要があります。 賢明な名前を選択すると、後で時間とエネルギーを節約できます。 名前から、特定の変数、関数、またはクラスが何を表すかを把握できます。 また、デバッグが困難なエラーを引き起こす可能性のある不適切な名前の使用も避けます。

Note:書体によっては、lO、またはIの1文字の名前を1および0と間違える可能性があるため使用しないでください。 :

O = 2  # This may look like you're trying to reassign 2 to zero

命名スタイル

以下の表は、Pythonコードの一般的な命名スタイルのいくつかと、それらをいつ使用すべきかを示しています。

Type 命名規則

関数

小文字の単語を使用してください。 読みやすさを向上させるために、単語をアンダースコアで区切ります。

functionmy_function

変数

小文字の1文字、単語、または単語を使用します。 読みやすさを向上させるために、単語をアンダースコアで区切ります。

xvarmy_variable

クラス

各単語は大文字で始めます。 単語をアンダースコアで区切らないでください。 このスタイルはキャメルケースと呼ばれます。

ModelMyClass

方法

小文字の単語を使用してください。 読みやすさを向上させるために、単語をアンダースコアで区切ります。

class_methodmethod

定数

大文字の1文字、単語、または単語を使用します。 読みやすさを向上させるために、単語をアンダースコアで区切ります。

CONSTANTMY_CONSTANTMY_LONG_CONSTANT

モジュール

短い小文字の単語を使用してください。 読みやすさを向上させるために、単語をアンダースコアで区切ります。

module.pymy_module.py

パッケージ

短い小文字の単語を使用してください。 単語をアンダースコアで区切らないでください。

packagemypackage

これらは、いくつかの一般的な命名規則とそれらの使用方法の例です。 ただし、読み取り可能なコードを記述するためには、文字と単語の選択に注意する必要があります。 コードで正しい命名スタイルを選択することに加えて、名前も慎重に選択する必要があります。 以下は、これを可能な限り効果的に行う方法に関するいくつかの指針です。

名前の選び方

変数、関数、クラスなどの名前を選択するのは難しい場合があります。 コードをより読みやすくするため、コードを記述するときは、命名の選択にかなりの量の考慮を払う必要があります。 Pythonでオブジェクトに名前を付ける最良の方法は、わかりやすい名前を使用して、オブジェクトが何を表しているかを明確にすることです。

変数に名前を付けるとき、xのような単純な1文字の小文字の名前を選択したくなるかもしれません。 ただし、数学関数の引数としてxを使用していない限り、xが何を表すかは明確ではありません。 人の名前を文字列として保存しており、文字列スライスを使用して名前の形式を変えたいとします。 次のような結果になる可能性があります。

>>>

>>> # Not recommended
>>> x = 'John Smith'
>>> y, z = x.split()
>>> print(z, y, sep=', ')
'Smith, John'

これは機能しますが、xy、およびzが何を表すかを追跡する必要があります。 共同制作者にとっても混乱を招く可能性があります。 より明確な名前の選択は、次のようなものになります。

>>>

>>> # Recommended
>>> name = 'John Smith'
>>> first_name, last_name = name.split()
>>> print(last_name, first_name, sep=', ')
'Smith, John'

同様に、入力する回数を減らすために、名前を選択するときに略語を使用することもできます。 以下の例では、単一の引数xを取り、それを2倍にする関数db()を定義しました。

# Not recommended
def db(x):
    return x * 2

一見、これは賢明な選択のように思えるかもしれません。 db()は簡単にdoubleの省略形になります。 しかし、数日後にこのコードに戻ることを想像してください。 この機能で何を達成しようとしていたかを忘れてしまった可能性があります。そのため、どのように短縮したかを推測するのが難しくなります。

次の例はより明確です。 書いてから数日後にこのコードに戻っても、この関数の目的を読んで理解することができます。

# Recommended
def multiply_by_two(x):
    return x * 2

同じ哲学が、Pythonの他のすべてのデータ型とオブジェクトに適用されます。 できるだけ簡潔でわかりやすい名前を使用してください。

コードレイアウト

「美しいのはいよりはましです。」

The Zen of Python

コードのレイアウト方法は、コードの読みやすさにおいて大きな役割を果たします。 このセクションでは、コードの読みやすさを改善するために垂直方向の空白を追加する方法を学びます。 また、PEP 8で推奨されている79文字の行制限を処理する方法も学習します。

空白行

垂直方向の空白、つまり空白行は、コードの可読性を大幅に向上させる可能性があります。 一緒にまとめられたコードは、圧倒的で読みにくい場合があります。 同様に、コードの空白行が多すぎると、コードが非常にまばらに見えるため、読者は必要以上にスクロールする必要がある場合があります。 以下は、垂直空白の使用方法に関する3つの重要なガイドラインです。

Surround top-level functions and classes with two blank lines.トップレベルの関数とクラスは、かなり自己完結型であり、個別の機能を処理する必要があります。 それらの周りに余分な垂直スペースを置くことは理にかなっています。

class MyFirstClass:
    pass


class MySecondClass:
    pass


def top_level_function():
    return None

Surround method definitions inside classes with a single blank line.クラス内では、関数はすべて互いに関連しています。 それらの間に1行だけを残すことをお勧めします。

class MyClass:
    def first_method(self):
        return None

    def second_method(self):
        return None

Use blank lines sparingly inside functions to show clear steps.複雑な関数は、returnステートメントの前にいくつかのステップを完了しなければならない場合があります。 読者が関数内のロジックを理解しやすくするために、各ステップの間に空白行を入れておくと役立ちます。

以下の例には、リストの分散を計算する関数があります。 これは2ステップの問題であるため、各ステップの間に空白行を残して各ステップを示しました。 returnステートメントの前にも空白行があります。 これにより、読者は返品内容を明確に確認できます。

def calculate_variance(number_list):
    sum_list = 0
    for number in number_list:
        sum_list = sum_list + number
    mean = sum_list / len(number_list)

    sum_squares = 0
    for number in number_list:
        sum_squares = sum_squares + number**2
    mean_squares = sum_squares / len(number_list)

    return mean_squares - mean**2

垂直方向の空白を慎重に使用すると、コードの可読性が大幅に向上します。 コードをセクションに分割する方法と、それらのセクションが互いにどのように関連するかを視覚的に理解するのに役立ちます。

最大行長と改行

PEP 8は、行を79文字に制限することを提案しています。 これは、行の折り返しを回避しながら、複数のファイルを隣り合わせに開くことができるためです。

もちろん、文を79文字以下に保つことは常に可能ではありません。 PEP 8では、ステートメントを複数の行にわたって実行できるようにする方法の概要を説明しています。

コードが括弧、括弧、または括弧内に含まれている場合、Pythonは行の継続を想定します。

def function(arg_one, arg_two,
             arg_three, arg_four):
    return arg_one

暗黙の継続を使用できない場合は、代わりにバックスラッシュを使用して行を分割できます。

from mypkg import example1, \
    example2, example3

ただし、暗黙の継続を使用できる場合は、そうする必要があります。

+*などの二項演算子の周囲で改行を行う必要がある場合は、演算子の前に行う必要があります。 このルールは数学に由来します。 数学者は、二項演算子の前にブレークすると読みやすさが向上することに同意します。 次の2つの例を比較してください。

以下は、バイナリ演算子の前にブレークする例です。

# Recommended
total = (first_variable
         + second_variable
         - third_variable)

演算子は操作対象の変数のすぐ隣にあるため、どの変数が加算または減算されているかをすぐに確認できます。

次に、二項演算子の後のブレークの例を見てみましょう。

# Not Recommended
total = (first_variable +
         second_variable -
         third_variable)

ここでは、どの変数が追加され、どの変数が減算されるかを確認するのが難しくなります。

バイナリ演算子の前にブレークすると、より読みやすいコードが生成されるため、PEP 8が推奨しています。 二項演算子が引き続きPEP8に準拠した後、consistentlyが破損するコード。 ただし、二項演算子の前にブレークすることをお勧めします。

インデント

「それを行うための明白な方法は1つ、できれば1つだけである必要があります。」

The Zen of Python

インデント、または先頭の空白は、Pythonで非常に重要です。 Pythonのコード行のインデントレベルにより、ステートメントをグループ化する方法が決まります。

次の例を見てください。

x = 3
if x > 5:
    print('x is larger than 5')

インデントされたprintステートメントは、ifステートメントがTrueを返す場合にのみ実行する必要があることをPythonに通知します。 同じインデントが適用され、関数が呼び出されたときに実行するコード、または特定のクラスに属するコードをPythonに伝えます。

PEP 8で規定されている主要なインデントルールは次のとおりです。

  • インデントを示すには、4つの連続したスペースを使用します。

  • タブよりもスペースを優先します。

タブと スペース

前述のように、コードをインデントするときは、タブではなくスペースを使用する必要があります。 [.kbd .key-tab]#Tab#キーを押すと、テキストエディタの設定を調整して、タブ文字の代わりに4つのスペースを出力できます。

Python 2を使用していて、コードをインデントするためにタブとスペースを組み合わせて使用​​している場合、実行しようとしてもエラーは表示されません。 一貫性を確認するために、コマンドラインからPython 2コードを実行するときに-tフラグを追加できます。 インタープリターは、タブとスペースの使用に矛盾がある場合に警告を発行します。

$ python2 -t code.py
code.py: inconsistent use of tabs and spaces in indentation

代わりに、-ttフラグを使用すると、インタープリターは警告ではなくエラーを発行し、コードは実行されません。 この方法を使用する利点は、インタープリターが矛盾の場所を通知することです。

$ python2 -tt code.py
  File "code.py", line 3
    print(i, j)
             ^
TabError: inconsistent use of tabs and spaces in indentation

Python 3では、タブとスペースを混在させることはできません。 したがって、Python 3を使用している場合、これらのエラーは自動的に発行されます。

$ python3 code.py
  File "code.py", line 3
    print(i, j)
              ^
TabError: inconsistent use of tabs and spaces in indentation

インデントを示すタブまたはスペースを使用してPythonコードを作成できます。 ただし、Python 3を使用している場合は、選択と一致している必要があります。 そうしないと、コードは実行されません。 PEP 8では、インデントを示すために常に4つの連続したスペースを使用することをお勧めします。

改行後のインデント

行の継続を使用して行を79文字未満に保つ場合、インデントを使用すると読みやすくなります。 これにより、読者は2行のコードと2行にわたる1行のコードを区別できます。 使用できるインデントには2つのスタイルがあります。

これらの最初の方法は、インデントされたブロックを開始区切り文字に揃えることです。

def function(arg_one, arg_two,
             arg_three, arg_four):
    return arg_one

場合によっては、開始区切り文字と位置合わせするために必要なスペースは4つだけであることがわかります。 これは、if、スペース、および開始ブラケットが4文字を構成するため、複数行にまたがるifステートメントでよく発生します。 この場合、ifステートメント内のネストされたコードブロックがどこから始まるかを判断するのが難しい場合があります。

x = 5
if (x > 3 and
    x < 10):
    print(x)

この場合、PEP 8は読みやすさを改善するために2つの代替手段を提供します。

  • 最終条件の後にコメントを追加します。 ほとんどのエディターでは構文が強調表示されるため、これにより条件がネストされたコードから分離されます。

    x = 5
    if (x > 3 and
        x < 10):
        # Both conditions satisfied
        print(x)
  • 行の継続に追加のインデントを追加します。

    x = 5
    if (x > 3 and
            x < 10):
        print(x)

改行に続くインデントの代替スタイルは、hanging indentです。 これは、段落またはステートメントの最初の行以外のすべての行がインデントされることを意味する印刷上の用語です。 ぶら下げインデントを使用して、コード行の続きを視覚的に表すことができます。 例を示しましょう。

var = function(
    arg_one, arg_two,
    arg_three, arg_four)

Note:ぶら下がっているインデントを使用している場合、最初の行に引数があってはなりません。 次の例は、PEP 8に準拠していません。

# Not Recommended
var = function(arg_one, arg_two,
    arg_three, arg_four)

ぶら下げインデントを使用する場合は、追加のインデントを追加して、関数内に含まれるコードから継続行を区別します。 次の例は、関数内のコードが継続行と同じインデントレベルにあるため、読みにくくなっています。

# Not Recommended
def function(
    arg_one, arg_two,
    arg_three, arg_four):
    return arg_one

代わりに、行の継続で二重インデントを使用することをお勧めします。 これにより、関数の引数と関数本体を区別しやすくなり、読みやすくなります。

def function(
        arg_one, arg_two,
        arg_three, arg_four):
    return arg_one

PEP 8準拠のコードを記述する場合、79文字の行制限により、コードに改行を追加する必要があります。 読みやすさを改善するには、継続行をインデントして、継続行であることを示す必要があります。 これを行うには2つの方法があります。 1つ目は、インデントされたブロックを開始区切り文字に揃えることです。 2つ目は、ぶら下げインデントを使用することです。 改行の後に使用するインデント方法を自由に選択できます。

閉じブレースを配置する場所

行の継続により、括弧、括弧、または括弧内の行を分割できます。 閉じ括弧を忘れるのは簡単ですが、賢明な場所に置くことが重要です。 そうしないと、読者を混乱させる可能性があります。 PEP 8は、暗黙の行の継続における閉じ括弧の位置に2つのオプションを提供します。

  • 前の行の最初の非空白文字で右中括弧を並べます:

    list_of_numbers = [
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
        ]
  • 構成要素を開始する行の最初の文字と右中括弧を並べます。

    list_of_numbers = [
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
    ]

使用するオプションを自由に選択できます。 しかし、いつものように、一貫性が重要なので、上記の方法のいずれかに固執するようにしてください。

「実装の説明が難しい場合、それは悪い考えです。」

The Zen of Python

コメントを使用して、記述されたとおりにコードを文書化する必要があります。 コードを文書化して、あなたと共同編集者が理解できるようにすることが重要です。 あなたまたは他の誰かがコメントを読むとき、彼らはコメントが適用されるコードとそれがあなたのコードの他の部分にどのように適合するかを簡単に理解できるはずです。

コードにコメントを追加する際に覚えておくべき重要なポイントを次に示します。

  • コメントとdocstringの行の長さを72文字に制限します。

  • 大文字で始まる完全な文を使用してください。

  • コードを変更する場合は、コメントを更新してください。

ブロックコメントを使用して、コードの小さなセクションを文書化します。 ファイルからデータをインポートする、データベースエントリを更新するなど、単一のアクションを実行するために複数行のコードを記述する必要がある場合に便利です。 これらは、特定のコードブロックの目的と機能を他の人が理解するのに役立つため、重要です。

PEP 8は、ブロックコメントを記述するために次のルールを提供します。

  • ブロックコメントを、それらが記述するコードと同じレベルにインデントします。

  • 各行を#で開始し、その後に1つのスペースを続けます。

  • 単一の#を含む行で段落を区切ります。

これは、forループの機能を説明するブロックコメントです。 79文字の行制限を維持するために、文が改行で折り返されることに注意してください。

for i in range(0, 10):
    # Loop over i ten times and print out the value of i, followed by a
    # new line character
    print(i, '\n')

コードが非常に技術的なものである場合は、ブロックコメントで複数の段落を使用する必要がある場合があります。

def quadratic(a, b, c, x):
    # Calculate the solution to a quadratic equation using the quadratic
    # formula.
    #
    # There are always two solutions to a quadratic equation, x_1 and x_2.
    x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
    x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    return x_1, x_2

どのタイプのコメントが適切であるか疑問がある場合は、コメントをブロックすることがよくあります。 コード全体で可能な限りそれらを使用しますが、コードを変更する場合は必ず更新してください!

インラインコメントは、コード内の単一のステートメントを説明します。 特定のコード行が必要な理由を思い出させたり、他の人に説明するのに役立ちます。 PEP 8がそれらについて述べなければならないことは次のとおりです。

  • インラインコメントは慎重に使用してください。

  • 参照するステートメントと同じ行にインラインコメントを記述します。

  • インラインコメントは、ステートメントから2つ以上のスペースで区切ります。

  • ブロックコメントのように、#と単一のスペースでインラインコメントを開始します。

  • 明白な説明のためにそれらを使用しないでください。

以下は、インラインコメントの例です。

x = 5  # This is an inline comment

インラインコメントが必要なように見える場合もありますが、代わりにより良い命名規則を使用できます。 例を示しましょう。

x = 'John Smith'  # Student Name

ここで、インラインコメントは追加情報を提供します。 ただし、人の名前の変数名としてxを使用することは悪い習慣です。 変数の名前を変更する場合、インラインコメントは不要です。

student_name = 'John Smith'

最後に、これらのようなインラインコメントは、明確で煩雑なコードを述べているため、悪い習慣です。

empty_list = []  # Initialize empty list

x = 5
x = x * 5  # Multiply x by 5

インラインコメントはブロックコメントよりも具体的であり、不要な場合は簡単に追加できるため、混乱が生じます。 ブロックコメントを使用するだけで済むので、インラインコメントが必要であることが確実でない限り、ブロックコメントに固執するとコードはPEP 8に準拠する可能性が高くなります。

ドキュメント文字列

ドキュメント文字列、またはdocstringは、関数、クラス、メソッド、またはモジュールの最初の行に表示される二重引用符(""")または単一引用符(''')で囲まれた文字列です。 これらを使用して、特定のコードブロックを説明および文書化できます。 docstringをカバーするPEP全体PEP 257がありますが、このセクションで要約を取得します。

docstringに適用される最も重要なルールは次のとおりです。

  • """This is a docstring"""のように、docstringを両側を3つの二重引用符で囲みます。

  • すべてのパブリックモジュール、関数、クラス、およびメソッドに対してそれらを記述します。

  • 複数行のdocstringを終了する"""を1行に単独で配置します。

    def quadratic(a, b, c, x):
        """Solve quadratic equation via the quadratic formula.
    
        A quadratic equation has the following form:
        ax**2 + bx + c = 0
    
        There always two solutions to a quadratic equation: x_1 & x_2.
        """
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2
  • 1行のdocstringの場合、"""を同じ行に保持します。

    def quadratic(a, b, c, x):
        """Use the quadratic formula"""
        x_1 = (- b+(b**2-4*a*c)**(1/2)) / (2*a)
        x_2 = (- b-(b**2-4*a*c)**(1/2)) / (2*a)
    
        return x_1, x_2

Pythonコードの文書化に関する詳細な記事については、James MertzによるDocumenting Python Code: A Complete Guideを参照してください。

式とステートメントの空白

「スパースは、デンスよりも優れています。」

The Zen of Python

空白は、適切に使用すると式やステートメントで非常に役立ちます。 十分な空白がない場合、コードはすべてまとめられるため、読みにくくなる可能性があります。 空白が多すぎると、関連する用語をステートメントで視覚的に組み合わせることが困難になる場合があります。

二項演算子の周りの空白

次の2項演算子を、両側に1つのスペースで囲みます。

  • 代入演算子(=+=-=など)

  • 比較(==!=><>=<=)および(isis notinnot in

  • ブール値(andnotor

Note=を使用して関数の引数にデフォルト値を割り当てる場合は、スペースで囲まないでください。

# Recommended
def function(default_parameter=5):
    # ...


# Not recommended
def function(default_parameter = 5):
    # ...

ステートメントに複数の演算子が含まれる場合、各演算子の前後に1つのスペースを追加すると混乱する場合があります。 代わりに、特に数学的な操作を実行する場合は、優先度が最も低い演算子の周りに空白のみを追加することをお勧めします。 いくつか例を挙げます。

# Recommended
y = x**2 + 5
z = (x+y) * (x-y)

# Not Recommended
y = x ** 2 + 5
z = (x + y) * (x - y)

複数の条件があるifステートメントにこれを適用することもできます。

# Not recommended
if x > 5 and x % 2 == 0:
    print('x is larger than 5 and divisible by 2!')

上記の例では、and演算子の優先度が最も低くなっています。 したがって、ifステートメントを次のように表現する方が明確な場合があります。

# Recommended
if x>5 and x%2==0:
    print('x is larger than 5 and divisible by 2!')

演算子の両側で同じ量の空白を使用する必要があるという注意事項を使用して、どちらを明確にするかを自由に選択できます。

以下は受け入れられません。

# Definitely do not do this!
if x >5 and x% 2== 0:
    print('x is larger than 5 and divisible by 2!')

スライスでは、コロンは二項演算子として機能します。 したがって、前のセクションで説明した規則が適用され、どちらの側にも同じ量の空白が存在するはずです。 次のリストスライスの例は有効です。

list[3:4]

# Treat the colon as the operator with lowest priority
list[x+1 : x+2]

# In an extended slice, both colons must be
# surrounded by the same amount of whitespace
list[3:4:5]
list[x+1 : x+2 : x+3]

# The space is omitted if a slice parameter is omitted
list[x+1 : x+2 :]

要約すると、ほとんどの演算子は空白で囲む必要があります。 ただし、関数の引数や、1つのステートメントで複数の演算子を組み合わせる場合など、この規則にはいくつかの注意事項があります。

空白を追加しない場合

場合によっては、空白を追加するとコードが読みにくくなることがあります。 余白が多すぎると、コードが過度にまばらになり、追跡が難しくなります。 PEP 8は、空白が不適切な非常に明確な例を概説しています。

空白の追加を避けるための最も重要な場所は行末です。 これはtrailing whitespaceとして知られています。 目に見えないため、トレースが困難なエラーが発生する可能性があります。

次のリストは、空白の追加を避ける必要があるいくつかのケースの概要を示しています。

  • 括弧、括弧、または中括弧のすぐ内側:

    # Recommended
    my_list = [1, 2, 3]
    
    # Not recommended
    my_list = [ 1, 2, 3, ]
  • コンマ、セミコロン、またはコロンの前:

    x = 5
    y = 6
    
    # Recommended
    print(x, y)
    
    # Not recommended
    print(x , y)
  • 関数呼び出しの引数リストを開始する開き括弧の前:

    def double(x):
        return x * 2
    
    # Recommended
    double(3)
    
    # Not recommended
    double (3)
  • インデックスまたはスライスを開始するオープンブラケットの前:

    # Recommended
    list[3]
    
    # Not recommended
    list [3]
  • 末尾のコンマと閉じ括弧の間:

    # Recommended
    tuple = (1,)
    
    # Not recommended
    tuple = (1, )
  • 代入演算子を整列するには:

    # Recommended
    var1 = 5
    var2 = 6
    some_long_var = 7
    
    # Not recommended
    var1          = 5
    var2          = 6
    some_long_var = 7

コードの末尾に空白がないことを確認してください。 PEP 8では、ブラケットのすぐ内側やコンマやコロンの前など、余分な空白を追加することをお勧めしません。 また、演算子を揃えるために余分な空白を追加しないでください。

プログラミングの推奨事項

「単純なものは複雑なものより優れています。」

The Zen of Python

Python(および他のプログラミング言語)で同様のアクションを実行する方法がいくつかあることがよくわかります。 このセクションでは、PEP 8が提供するいくつかの提案を参照して、あいまいさを取り除き、一貫性を維持します。

Don’t compare boolean values to True or False using the equivalence operator.ブール値がTrueかFalseかを確認する必要があることがよくあります。 そうするとき、以下のようなステートメントでこれを行うことは直感的です:

# Not recommended
my_bool = 6 > 5
if my_bool == True:
    return '6 is bigger than 5'

ここでは、等価演算子==を使用する必要はありません。 boolは、TrueまたはFalseの値のみを取ることができます。 以下を書くだけで十分です。

# Recommended
if my_bool:
    return '6 is bigger than 5'

ブール値を使用してifステートメントを実行するこの方法は、必要なコードが少なく、単純であるため、PEP8で推奨されています。

Use the fact that empty sequences are falsy in if statements.リストが空かどうかを確認したい場合は、リストの長さを確認したくなるかもしれません。 リストが空の場合、その長さは0であり、ifステートメントで使用した場合のFalseと同等です。 例を示しましょう。

# Not recommended
my_list = []
if not len(my_list):
    print('List is empty!')

ただし、Pythonでは、空のリスト、文字列、またはタプルはfalsyです。 したがって、上記のより簡単な代替案を考え出すことができます。

# Recommended
my_list = []
if not my_list:
    print('List is empty!')

どちらの例でもList is empty!が出力されますが、2番目のオプションの方が単純なので、PEP8で推奨されています。

Use is not rather than not ... is in if statements.変数に定義された値があるかどうかを確認しようとしている場合、2つのオプションがあります。 1つ目は、以下の例のように、ifステートメントをx is not Noneで評価することです。

# Recommended
if x is not None:
    return 'x exists!'

2番目のオプションは、x is Noneを評価してから、notの結果に基づいてifステートメントを作成することです。

# Not recommended
if not x is None:
    return 'x exists!'

両方のオプションが正しく評価されますが、最初の方が簡単なので、PEP 8が推奨します。

Don’t use if x: when you mean if x is not None:.場合によっては、デフォルトでNoneである引数を持つ関数がある場合があります。 このような引数argに別の値が指定されているかどうかを確認する際のよくある間違いは、次を使用することです。

# Not Recommended
if arg:
    # Do something with arg...

このコードは、argが真実であることを確認します。 代わりに、argnot Noneであることを確認する必要があるため、次を使用することをお勧めします。

# Recommended
if arg is not None:
    # Do something with arg...

ここで行われている間違いは、not Noneとtruthyが同等であると想定していることです。 arg = []を設定することもできます。 上で見たように、空のリストはPythonで偽と評価されます。 したがって、引数argが割り当てられていても、条件が満たされないため、ifステートメントの本文のコードは実行されません。

Use .startswith() and .endswith() instead of slicing.文字列wordの前にcatという単語が付いているかどうかを確認しようとしている場合は、list slicingを使用するのが賢明と思われるかもしれません。 ただし、リストのスライスはエラーを起こしやすいため、プレフィックスまたはサフィックスの文字数をハードコーディングする必要があります。 Pythonリストに精通していない人があなたが達成しようとしているものをスライスすることも明確ではありません:

# Not recommended
if word[:3] == 'cat':
    print('The word starts with "cat"')

ただし、これは.startswith()を使用するほど読みやすくありません。

# Recommended
if word.startswith('cat'):
    print('The word starts with "cat"')

同様に、接尾辞を確認するときも同じ原則が適用されます。 以下の例は、文字列がjpgで終わるかどうかを確認する方法の概要を示しています。

# Not recommended
if file_name[-3:] == 'jpg':
    print('The file is a JPEG')

結果は正しいが、表記は少し不格好で読みにくい。 代わりに、以下の例のように.endswith()を使用できます。

# Recommended
if file_name.endswith('jpg'):
    print('The file is a JPEG')

これらのプログラミングの推奨事項のほとんどと同様に、目標は読みやすさとシンプルさです。 Pythonには、同じアクションを実行するさまざまな方法があるため、どのメソッドを選択するかのガイドラインが役立ちます。

PEP 8を無視する場合

この質問に対する短い答えは決してありません。 PEP 8に従ってレターを作成すれば、クリーンでプロフェッショナルで読みやすいコードを確実に入手できます。 これは、共同作業者や潜在的な雇用者だけでなく、あなたにとっても有益です。

ただし、PEP 8の一部のガイドラインは、次の場合には不便です。

  • PEP 8に準拠すると、既存のソフトウェアとの互換性が損なわれる場合

  • 作業内容を取り巻くコードがPEP 8と矛盾している場合

  • コードが古いバージョンのPythonとの互換性を維持する必要がある場合

コードがPEP 8に準拠していることを確認するためのヒントとコツ

コードがPEP 8に準拠していることを確認することを忘れないでください。 コードを開発する際に、これらのすべてのルールを覚えるのは大変なことです。 特に過去のプロジェクトをPEP 8に準拠するように更新するには時間がかかります。 幸いなことに、このプロセスをスピードアップするのに役立つツールがあります。 PEP 8コンプライアンスを実施するために使用できるツールには、リンターとオートフォーマッターの2つのクラスがあります。

リンター

リンターは、コードを分析してエラーにフラグを立てるプログラムです。 エラーの修正方法に関する提案を提供します。 リンターは、テキストエディターの拡張機能としてインストールした場合に特に役立ちます。これは、作成中にエラーや文体の問題にフラグを立てるためです。 このセクションでは、リンターの仕組みの概要と、最後にテキストエディター拡張機能へのリンクが表示されます。

Pythonコードに最適なリンターは次のとおりです。

  • pycodestyleは、PythonコードをPEP8のいくつかのスタイル規則と照合するためのツールです。

    pipを使用してpycodestyleをインストールします。

    $ pip install pycodestyle

    次のコマンドを使用して、ターミナルからpycodestyleを実行できます。

    $ pycodestyle code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:6:19: E711 comparison to None should be 'if cond is None:'
  • flake8は、デバッガーpyflakespycodestyleを組み合わせたツールです。

    pipを使用してflake8をインストールします。

    $ pip install flake8

    次のコマンドを使用して、ターミナルからflake8を実行します。

    $ flake8 code.py
    code.py:1:17: E231 missing whitespace after ','
    code.py:2:21: E231 missing whitespace after ','
    code.py:3:17: E999 SyntaxError: invalid syntax
    code.py:6:19: E711 comparison to None should be 'if cond is None:'

    出力の例も示されています。

Note:出力の余分な行は、構文エラーを示します。

これらは、AtomSublime Texthttps://code.visualstudio.com/docs/python/linting#flake8[Visual Studio Code], and VIM. You can also find guides on setting up Sublime Text and VIM for Python development, as well as an overview of some popular text editors at _Real Pythonの拡張子としても使用できます。

オートフォーマッター

オートフォーマッタは、コードをリファクタリングしてPEP 8に自動的に準拠するプログラムです。 そのようなプログラムがblackになると、PEP 8のルールのmostに従ってコードが自動フォーマットされます。 大きな違いの1つは、行の長さが79文字ではなく88文字に制限されていることです。 ただし、次の例に示すように、コマンドラインフラグを追加してこれを上書きできます。

pipを使用してblackをインストールします。 実行するにはPython 3.6以降が必要です。

$ pip install black

リンターと同様に、コマンドラインから実行できます。 code.pyというファイルで、PEP8に準拠していない次のコードから始めたとします。

for i in range(0,3):
    for j in range(0,3):
        if (i==2):
            print(i,j)

その後、コマンドラインから次のコマンドを実行できます。

$ black code.py
reformatted code.py
All done! ✨ 🍰 ✨

code.pyは、次のように自動的に再フォーマットされます。

for i in range(0, 3):
    for j in range(0, 3):
        if i == 2:
            print(i, j)

行の長さの制限を変更する場合は、--line-lengthフラグを使用できます。

$ black --line-length=79 code.py
reformatted code.py
All done! ✨ 🍰 ✨

他の2つのオートフォーマッタ、autopep8yapfは、blackと同様のアクションを実行します。

別のReal Pythonチュートリアル、Alexander van TolによるPython Code Quality: Tools & Best Practicesは、これらのツールの使用方法の完全な説明を提供します。

結論

これで、PEP 8で規定されたガイドラインを使用して、高品質で読み取り可能なPythonコードを作成する方法がわかりました。 ガイドラインは見栄えが良いように見えますが、特に潜在的な雇用者または協力者とコードを共有する場合は、ガイドラインに従うことでコードを本当に改善できます。

このチュートリアルでは、次のことを学びました。

  • PEP 8とは何か、なぜ存在するのか

  • PEP 8準拠のコードを書くことを目指すべき理由

  • PEP 8準拠のコードを書く方法

さらに、リンターとオートフォーマッターを使用して、PEP 8ガイドラインに照らしてコードをチェックする方法も確認しました。

PEP 8について詳しく知りたい場合は、full documentationを読むか、同じ情報が含まれているが適切にフォーマットされているpep8.orgにアクセスしてください。 これらのドキュメントには、このチュートリアルでカバーされていないPEP 8ガイドラインの残りの部分があります。