1. はじめに:リンター・フォーマッター・PEP8とは
1.1. リンター・フォーマッターとは
リンター・フォーマッターとは、ある一定のルールに従って、プログラムに対して警告や修正をしてくれるツールです。警告や修正の対象としては、そもそも実行できない構文エラーから、こうしたほうが読みやすいという指摘まで、様々です。
リンターとフォーマッターの違いは、ざっくり以下の認識で特に問題ないです。(厳密な定義は少し違うようですが。)
- リンター … 情報提供や警告を表示してくれるが、プログラムの修正まではしない
- フォーマッター … プログラムの修正まで実行する
1.2. PEP8とは
PEP8(ペップエイト)とは、Pythonスクリプトの書き方の公式ルールで、Pythonコア開発者のGuido van Rossumを含むチームによってまとめられたものです。
PEP8が規定された主な目的は、スクリプトの書き方の一貫性と可読性(読みやすさ)を向上させることです。これにより、他の人や昔の自分が作ったスクリプトを簡単に理解できるようになり(保守性が高くなり)、開発コストを抑えることができます。
具体的には、以下のようなルール(コーディング規約)が規定されています。PEP8の全文は、脚注1のリンクを参照ください。
- インデントは半角スペース4つとする。
- 1行の長さは79文字まで(ただしプロジェクト内限定で統一できるなら、99文字まででもOK)。
- トップレベルのメソッドやクラスの間は2行空け、クラス内のメソッド間は1行空ける。
- import文はファイルの先頭に配置し、「標準ライブラリ」→「サードパーティー」→「自作ライブラリ」の順に空行を挟んでグループ分けする。
- 文字列を定義する引用符は、シングル「’」とダブル「”」のどちらを使っても良いが、プロジェクト内で統一する。
1.3. PEP8準拠のリンター・フォーマッター
PEP8に従うリンター・フォーマッターを設定したエディタでPython開発を行うことで、Pythonコア開発者の思想に準拠した、読みやすいスクリプトを誰でも簡単に書くことができます。
本記事では、Pythonの最もメジャーなエディタ・統合開発環境であるVisual Studio Code(以下、VS Code)に、PEP8準拠のリンター・フォーマッターを設定する方法をお伝えします。
2. 【結論】VS CodeにPEP8準拠のリンター・フォーマッターを設定する方法(Flake8+Black Formatter)
この章の手順を踏めば、誰でも簡単にPEP8に準拠したPythonスクリプトを書くことができるようになります。特に、設定ファイルはコピペするだけでOKです。(本記事の動作環境は脚注2を参照。)
2.1. Python開発環境の構築
まずは、VS CodeでPython開発ができる状態まで環境構築をお願いします。Windowsの場合は、以下の記事を参考にしてください。
2.2. リンター・フォーマッターのインストール
次に、リンター・フォーマッター4つを、VS Codeの拡張機能としてそれぞれインストールしてください。
表1. VS Codeにインストールするリンター・フォーマッター
ツール名 | 説明 |
---|---|
Flake8 [リンター(メイン)] | PEP8に従って情報や警告を表示してくれる(3つのリンター3をまとめたもの) |
Mypy Type Checker [リンター(補助)] | Pythonの「型ヒント」に関する規約(PEP484)に従って、情報や警告を表示してくれる |
Black Formatter [フォーマッター(メイン)] | PEP8に従ってスクリプトを自動修正してくれる |
isort [フォーマッター(補助)] | PEP8のimport文に関する規約に従って、import文を自動で並び替えてくれる |
以下の手順を繰り返すことで、4つそれぞれをインストールできます。
- VS Codeウィンドウのサイドメニューにある「田」のようなアイコンをクリックします。(カーソルを乗せると「拡張機能」と表示されます。)
- 検索ボックスが選択状態になるので、上記表1の「ツール名」を入力して検索します。【画面スクショ4】
- 「Microsoft」の青いバッジが表示されている、対象の拡張機能が一覧に表示されるので、「インストール」をクリックします。
- しばらくすると対象の拡張機能のインストールが完了します。
2.3. リンター・フォーマッターの設定をコピー&ペースト
VS Codeの設定ファイルに、リンター・フォーマッターの設定(下記)をそのままコピー&ペーストしてください。設定ファイルに既に別の設定が書き込まれている場合は、波括弧「{}」の中身を、既存設定の波括弧「{}」内の末尾に追記するなどの方法で、既存設定と結合してください。
VS Codeの設定ファイル(ユーザー設定、またはワークスペース設定)の開き方は、こちらの記事が参考になります。
{
/* エディタ設定 - エディタ画面の指定文字目の位置に縦線を表示する */
// Pythonの1行の目安として表示する(別の言語でも表示されないように、ワークスペース設定にするのがおすすめ)
"editor.rulers": [
88, // ★①PEP8では1行79文字までを規定しているが、Black Formatterのデフォルト値は88文字
],
/* 拡張機能設定 - Python設定 */
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter", // デフォルトのフォーマッターをBlack Formatterに
"editor.formatOnSave": true, // ★②保存時にデフォルトのフォーマッターを実行
"editor.codeActionsOnSave": {
"source.organizeImports": "explicit", // 保存時にフォーマッターisortを実行
},
},
/* 拡張機能設定 - リンター・フォーマッター設定 */
// リンター設定
// Flake8 (PyFlakes + pycodestyle + Ned Batchelder’s McCabe script): メインのリンター
"flake8.args": [
"--max-line-length=99", // ★③1行がこの文字数を超えたら警告(デフォルト:79文字)
"--extend-ignore=E203,E701,W503,W504", // ★④デフォルトに加えて、指定したエラー・警告を表示させなくする
// E203: Black Formatterのフォーマットにより必ず表示されるエラーを抑制(スライスの「:」の前の空白をエラーとする)
// E701: Black Formatterのフォーマットにより必ず表示されるエラーを抑制(クラスおよび関数を一行で実装していたらエラーとする)
// W503: Black Formatterのフォーマットにより必ず表示される警告を抑制(演算子直前の改行を警告する)
// W504: Black Formatterのフォーマットにより必ず表示される警告を抑制(演算子直後の改行を警告する)
],
// Mypy Type Checker: 「型ヒント」の規定(PEP484)に従って警告する
"mypy-type-checker.args": [
"--check-untyped-defs", // 型ヒントがついていないメソッド内についても型ヒントをチェックする
],
// フォーマッター設定
// Black Formatter: メインのフォーマッター
"black-formatter.args": [
"--line-length=99", // ★⑤1行がこの文字数を超えたら可能な限り強制的に改行(デフォルト:88文字)
"--skip-string-normalization", // ★⑥シングル->ダブルクォーテーションの変換をしないようにする
],
// isort: PEP8に従って、import文を自動的に並べ替える
"isort.args": ["--profile", "black"], // Black Formatterと挙動が競合しないようにする
}
※「★」でマークしている設定6か所については、個人またはプロジェクトの合意に応じて、適宜修正をして利用してください。
- ②:保存時ではなく手動でBlack Formatterを適用する場合は、設定ファイルからこの1行を削除します。エディタ上でスクリプトの一部を範囲選択し、「Ctrl + K → Ctrl + F」のショートカットをタイプすることにより、選択した範囲のみにBlack Formatterを適用できます(Mac OSの場合は「Ctrl」を「Cmd」に読み替え)。ただし、isortについては”editor.codeActionsOnSave”によって別途定義されているので、②の行の設定を削除しても保存時に自動適用されます。
- ④:Flake8のエラーコードは以下のページで一覧を確認できます。Flake8はE121, E123, E126, E226, E24, E704, W503, W504のエラー・警告をデフォルトで抑制していて5、それに加えて上記のE203, E701, W503, W504を抑制するよう設定しています。これはBlack Formatterのフォーマット処理との競合対策ですが、Black Formatterが公式にE203, E701の抑制を推奨している6ほか、W503, W504の抑制を薦めている記事7があったため設定しています。これら以外に抑制したいエラー・警告がある場合は、設定ファイルに対象のエラーコードを追記します。
2.4. リンター・フォーマッターの動作確認
実際にPythonスクリプトを作成して、リンター・フォーマッターが動作することを確認してみましょう。
VS Code上で新しいPythonファイルを作成し、以下のスクリプト(PEP8非準拠)をペーストして保存してみてください。保存すると同時に、フォーマッターの機能によりPEP8に従うように自動修正され、またリンターの機能によりPEP8に従えていない箇所が警告表示されることがわかります。【画面スクショ8】
なお「numpy」はサードパーティーのライブラリなので、以下のスクリプトを実行するためにはpip install numpy
によりインストールしておく必要があります。また、標準ライブラリ「typing」はPython3.5以降追加されたライブラリであるため、それより前のバージョンのPythonでは動作しません(「型ヒント」の機能自体が存在しません)。
# 以下のインポート文の順番は「標準ライブラリ」→「サードパーティー」の順になっていないので、
# VS Codeのエディタ上で保存すると、isortにより順番が修正され、間に空行が自動挿入されます。
from typing import List
import numpy as np
import datetime
# 以下のコメントは長すぎて、VS Codeのエディタ上で、Flake8により警告を受けます。
# 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
class MyClass:
def __init__(self):
print('これはクラスのコンストラクターです。')
def my_instance_method(self):
print('これはインスタンスメソッドです。')
now_dt = datetime.datetime.now()
print(now_dt.strftime('%Y/%m/%d %H:%M:%S'))
# トップレベルのクラスやメソッドの間は2行空いていないといけないので、
# VS Codeのエディタ上で保存すると、自動的にこの上に空行が挿入されます。
def my_method():
print('これはメソッドです。')
# 変数random_int_ndarrayに対して、整数型のリストとして「型ヒント」を付与しているが、
# 実際のrandom_generator.integers()の戻り値はnumpyのndarrayであるので、
# Mypy Type Checkerにより警告を受けます。
random_generator = np.random.default_rng()
random_int_ndarray: List[int] = random_generator.integers(10, size=10)
print(random_int_ndarray)
# 1行が指定文字数を超えている場合、VS Codeのエディタ上で保存すると、自動的に改行されます。
print('この文は長すぎて、VS Codeのエディタ上で保存すると、Black Formatterによりprint文が自動で改行させられます。')
# 引用符のシングル・ダブル混在については、Black Formatterの設定で許容しているので、
# VS Codeのエディタ上で保存しても、修正されません。(--skip-string-normalization)
print("Black Formatterの設定次第では、文字列の引用符をダブルクォーテーションに統一できます。")
if __name__ == '__main__':
# このif文の中身は、インデントが半角スペース3文字になっているので、
# VS Codeのエディタ上で保存すると、自動的に半角スペース4文字に修正されます。
my_class = MyClass()
my_class.my_instance_method()
my_method()
3. 補足:Pythonで利用できるその他のリンター・フォーマッター
3.1. Pythonで利用できるリンター・フォーマッター
補足しておくと、Pythonで利用できるリンター・フォーマッターには、Flake8・Black Formatter以外にも色々あります。
表2. Pythonで利用できる主なリンター
表3. Pythonで利用できる主なフォーマッター
3.2. 本記事でFlake8+Black Formatterを採用している理由
では、複数のリンター・フォーマッターの選択肢がある中で、なぜ本記事ではFlake8+Blackを採用したかというと、いずれのツールもリリースから時間が経過し、かつ多くのプロジェクトに支持された実績があり、複数の参考記事が見つかったからです。
参考記事が多くあることで、今回改めて設定ファイルを整備する上でも、また今後メンテナンスをする中でも困ることが少ないだろう、というのが採用した理由です。(本記事の設定ファイルは、脚注に記載の5つの記事を特に参考にさせていただきました[7] [9]111213。)
しかし、フォーマッターについては新しくRuffが台頭してきているようですし、今後また流行りは変わっていくと思われるので、その時々に応じて各自・各プロジェクトで判断して採用するのがよいかと思います。
特に、新しいPythonのプロジェクトを開始する際や、新しいメンバーが加入する際は、採用すべきリンター・フォーマッターの設定ファイルをプロジェクト内で共有してから開発を進めることで、開発コスト全体の大きな削減につながるかと思います。
ここまで読んでいただき、ありがとうございました!
脚注
- PEP8で規定されているコーディング規約の全文
[原文] “PEP 8 – Style Guide for Python Code | peps.python.org”, https://peps.python.org/pep-0008/.
[日本語訳] “はじめに — pep8-ja 1.0 ドキュメント”, https://pep8-ja.readthedocs.io/ja/latest/. ↩︎ - 2章の手順の動作確認環境
・Windows 11 Home 23H2
・Python 3.11.9
・Visual Studio Code 1.95.2
・VS Code拡張機能「Python」2024.20.0
・VS Code拡張機能「Flake8」2023.10.0
・VS Code拡張機能「Mypy Type Checker」2024.0.0
・VS Code拡張機能「Black Formatter」2024.4.0
・VS Code拡張機能「isort」2023.10.1 ↩︎ - Flake8は、「PyFlakes」「pycodestyle」「Ned Batchelder’s McCabe script」の3つのリンターをまとめたツールです。ただし、3つ目のリンターMcCabeはデフォルトで無効になっています。 ↩︎
- (画面スクショ)VS Codeにおいて拡張機能をインストールする
↩︎ - “Full Listing of Options and Their Descriptions — flake8 documentation”, https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-ignore. ↩︎
- “Using Black with other tools – Black documentation”, https://black.readthedocs.io/en/stable/guides/using_black_with_other_tools.html#minimal-configuration. ↩︎
- “Pythonのコードフォーマッター(black)、リンター(flake8)をVSCode拡張機能で導入”, https://itc-engineering-blog.netlify.app/blogs/vscode-extensions-black-flake8. ↩︎
- (画面スクショ)リンター・フォーマッターの動作確認
[ファイル保存前]
[ファイル保存後]↩︎ - “Pythonのコードフォーマッターについての個人的ベストプラクティス #flake8 – Qiita”, https://qiita.com/sin9270/items/85e2dab4c0144c79987d. ↩︎
- “新しい静的コード解析ツール「Ruff」をご紹介 | gihyo.jp”, https://gihyo.jp/article/2023/03/monthly-python-2303. ↩︎
- “blackとflake8を使ったPython開発環境のセットアップ手順 | blog.lycheejam.net”, https://blog.lycheejam.net/posts/setup-python-dev-environment-with-black-and-flake8/. ↩︎
- “Pythonのリンター・フォーマッターをしっかりと理解する(Flake8, Black, isort, mypy)”, https://zenn.dev/tanny/articles/cdb555d6124a2a. ↩︎
- “mypyで静的型チェックを導入する – け日記”, https://ohke.hateblo.jp/entry/2020/10/03/230000. ↩︎