30
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NRI OpenStandiaAdvent Calendar 2024

Day 10

【令和6年最新版】初心者でも、チーム開発でも美しく!Python開発環境構築のすすめ

Last updated at Posted at 2024-12-09

はじめに

この記事の通りにPython開発環境の構築をすれば、初心者であっても、個人/チーム開発問わず可読性高く、一貫性のある美しいPythonプロジェクトの開発が進められることを目標にご紹介します。
コード品質を高めるための各種ツールをあらかじめ導入したPython開発環境で開発を進めることで、コードの品質が常に担保された状態(標準化された状態)を目指す方針とします。

美しいコードを書くべく開発環境に必要なもの

コードの品質を常に担保するのに必要なのは4点です。

No.  方法 役割
1 Linter PEP8」というコードの可読性や一貫性を持たせるPythonのコーディング規約を遵守できているか解析
2 Formatter PEP8に準拠していない部分を機械的に直せる範囲で自動修正
3 型チェック ※必要であれば Pythonの型ヒントに違反した実装を検知
4 Linter、Formatter、型チェックを強制する仕組み Linter、Formatter、型チェックを強制することでコードの品質が常に担保された状態にする

Linter、Formatter、型チェックのツール導入により開発者によってバラバラになりがちな書式の統一やエラーを孕むコードを事前に検知することができます。
ツール導入だけでなく、Linter、Formatter、型チェックを強制し、常に行われる開発環境にしておくことで、個人/チーム開発どちらの場合も可読性高く、一貫性のあるPythonプロジェクトを開発することができます。

image.png

この記事の使い方

この記事ではPythonに加えて、LinterとFormatter、必要であれば型チェックのツールをインストールしていきます。
Python開発環境の構成として以下のどちらかを構築できればOKです!

以降で編集するVSCodeのsettings.jsonについて(参考)

  • VSCode全体の設定として設定したい場合(ユーザー設定)
    VSCode上で「Ctrl+Shift+P」で表示されるメニューの中から「Open ユーザー設定を開く/User Settings(JSON)」を選択し、settings.jsonを開きます
  • 今回のプロジェクトだけに設定したい場合(ワークスペース設定)
    プロジェクトのルートディレクトリに.vscodeフォルダを作成し、作成したフォルダの中にsettings.jsonを新規作成します

0. Pythonをインストールする

Python公式ページからインストールしたいバージョンをダウンロードします。
ダウンロードしたinstallerを実行し、画面下部の「Add python.exe to PATH」にチェックを入れて「Install Now」をクリックします。
image.png
インストールが完了したらWindows Power Shellを開いてpython -Vを実行します。

$ python -V
Python 3.13.1

エラーにならず、インストールしたバージョンが表示されていればインストールは成功です。もしエラーになった場合はPCを再起動してから再度実行をお試しください。

1. Linter + 2. Formatterの最強ツール

Ruff (推奨度:★★★★★)

近年急速に勢力を拡大しているのがRuffです。その勢いはGithub Starsの推移を見ても明らかです。

RuffはLinterとFormatterの両方の機能を持っています。
それだけでもすごいのですがRustで実装されているため他のLinter、Formatterと比べて動作が高速という才色兼備なツールです。
一部対応していないものもありますが、Ruffを入れておけば後で紹介するFlake8+Black+isortとほぼ同等の機能をカバーできるので、正直Ruffを入れておけばLinter、Formatterは十分かなという印象です。

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「Ruff」を検索し、インストール
image.png
「settings.json」に以下を加筆することで、Linter、Formatter両方を設定することができます。

settings.json
{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit"
            "source.organizeImports": "explicit"
        }
    },
}
プロンプトでpipインストール・実行
pip install ruff # ruffをインストール

ruff check # 全てのファイルに対してLint実行する場合
ruff format # 全てのファイルに対してFormat実行する場合

Ruffオススメの初期設定

Ruffを最大限活かすために、Ruffに設定を追加します。
プロジェクトのルートディレクトリにpyproject.tomlファイルを作成し、設定を記述します。

pyproject.toml
[tool.ruff]
line-length = 120
indent-width = 4

[tool.ruff.lint]
select = ["E4", "E7", "E9", "F"]
ignore = []
fixable = ["ALL"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"

VSCodeのプラグインに設定を反映する

VSCodeのsettings.jsonにRuffの設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit"
            "source.organizeImports": "explicit"
        }
    },
+   "ruff.lint.args": ["--config=pyproject.toml"],
+   "ruff.format.args": ["--config=pyproject.toml"]
}

3. 型チェック(オプション)

Pythonは動的型付けのためコーディングに型を意識する必要はありませんが、型安全に開発ができるように「型ヒント」という仕組みがあります。ただしあくまで"ヒント"のため以下のようなコードを書いたとしても実行するまでエラーになるか検知できません。

def sum(i: int, j: int) -> int:
    return i + j

sum("1", 2) #第一引数はintを期待しているがstrが渡されている

もし型安全にPythonプロジェクトの開発を行いたい場合、型ヒントに基づいた静的解析を行ってくれるライブラリを導入する必要があります。

3.1 mypy (推奨度:★★★★★)

mypyは先ほどのような型ヒントにそぐわないコードを検知し、事前にエラーとして報告してくれるため真に型安全な開発を行うことができます。
先ほどのコードをmypyにかけると以下のように型定義から外れている個所をエラーとして教えてくれます。

error: Argument 1 to "sum" has incompatible type "int"; expected "str"
Found 1 error in 1 file (checked 1 source file)

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「Mypy Type Checker」を検索し、インストール
image.png
インストールするだけで自動でmypyが実行されるようになります。

プロンプトでpipインストール・実行
pip install mypy # mypyをインストール

mypy mypythonfile.py # 特定のファイルに対して実行する場合
mypy . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

mypyは独自の設定を入れることで一部ルールの緩和や変更を行うことができます。
pyproject.tomlファイルに設定を記述します。

pyproject.toml
[tool.mypy]
python_version = "3.13"
no_strict_optional = true # Noneに関する型チェックを緩和するオプション

VSCodeのプラグインに対して設定する

VSCodeのsettings.jsonにmypyの設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "black-formatter",
          "editor.formatOnSave": true,
          "editor.codeActionsOnSave": {
              "source.organizeImports": "explicit"
              }
    },
    "black-formatter.args":["--config", "pyproject.toml"],
    "isort.args":["--settings-file", "pyproject.toml"]
+    "mypy-type-checker.args": [
+        "--config-file=pyproject.toml"
+    ],
}

4. Linter、Formatter、型チェックを強制する

Linter、Formatter、型チェックを導入しても実行されなければ意味がありません。
私たちのプロジェクトでは、これらの実行を強制する仕組みとして2つ採用しています。

  • VSCodeの設定としてコーディング中、保存時に実行する
  • GitのCommit時に強制的に実行する (Git hooks)

4.1 VSCodeの設定としてコーディング中、保存時に実行する

先述してきた「VSCodeにインストール・実行」の手順を踏んでいれば、コーディング中や保存時に各ツールが実行されるように設定されているため、VSCodeでの開発に限りますが普段の開発体験に違和感なく取り込むことができます。

4.2 GitのCommit時に強制的に実行する (Git hooks)

個人開発、チーム開発どちらの場合でもGitによるコード管理を行っていれば、Git hooksの仕組みを利用することでGit commitの直前にLint、Format、型チェックを実行することができます。※前提として各ツールのpipインストールがされているものとします
Git hooksのpre-commitはGit commitの直前、pre-commitファイルに記述したshellスクリプトを実行する仕組みです。
pre-commitファイルにLint、Format、型チェックを実行するよう記述しておくことで、Lint、Format、型チェックのどこかでエラーが検出されるとCommitを完了することができなくなります。
これによってGit管理上100%発生するCommit時にLint、Format、型チェックを実行することができ、プロジェクト全体で統一性を保つことができます。

実装方法

プロジェクトの.git/hooks配下にpre-commitを新規作成し、

  1. Formatterによるフォーマット
  2. フォーマット結果をgit add
  3. Linterによる静的解析の実行
  4. 型チェックの実行

の順で実行されるように記述します。
以下はFormatterにBlackとisort、LinterにFlake8、型チェックにmypyを採用した場合の例です。ご自身が採用したツールに合わせて実行部分は適宜書き換えてください。

.git配下は通常Git管理されないものなので、チーム開発の場合は開発者にpre-commitファイルを配布し、各自.git/hooks配下に保存してもらう運用が必要になります

pre-commit
#!/bin/sh
# 自動フォーマット
echo -e "- フォーマット開始"
ruff format # Ruffの場合。Blackの場合は"black ."
if [ $? -ne 0 ]; then
  echo -e " \033[31;22m - フォーマット:失敗(Ruff)\033[0m\n"
  exit 1
fi

# isort . #isortの場合。Ruffの場合は不要
# if [ $? -ne 0 ]; then
#	echo -e " \033[31;22m - フォーマット:失敗(isort)\033[0m\n"
# exit 1
# fi

echo -e "\033[32;22m - フォーマット:完了\033[0m"
# フォーマット後の変更をadd
git add .

# Lintの検証
echo -e "- コードフォーマットチェック開始"
ruff check #Ruffの場合。Flake8の場合は"flake8 ."
if [ $? -ne 0 ]; then
    echo -e "\033[31;22m - コードフォーマットチェック:失敗\033[0m\n"
    exit 1
else
    echo -e "\033[32;22m - コードフォーマットチェック:成功\033[0m"
fi

# 型の検証(型チェックを行う場合)
echo -e "- 型チェック開始"
mypy .
if [ $? -ne 0 ]; then
	echo -e "\033[31;22m - 型チェック:失敗\033[0m\n"
  exit 1
else
	echo -e "\033[32;22m - 型チェック:成功\033[0m"
fi

exit 0
  • 実行結果(成功時)
    画像ddd.png

  • 実行結果(失敗時)
    失敗するとエラーになり、commit自体ができなくなります。
    画像ddddd.png

おわりに

いかがだったでしょうか?Linter、Formatter、型チェックが常に実施される開発環境でコーディングすることによって、自然と可読性や一貫性の高いコードでPythonプロジェクトになります。
Linterに指摘されないコードを意識して書く習慣がつけばツールに頼らずとも美しいコーディングができるようになると思うので、Pythonの環境構築の際はLinter、Formatter、型チェックも一緒に導入しておきましょう!

その他のLinter & Formatterツール紹介と導入方法

RuffはLinterとFormatterを併せ持ったツールですが、Ruff以外にもLinterとFormatterそれぞれに有名なツールが存在します。
Ruffが使われだしたのはつい最近の話なので、まだまだRuff以外のLinter、Formatterを採用しているプロジェクトも多くあります。
より厳密に静的解析したい場合などは、LinterとFormatterを個別に選択して導入しましょう。
ここからは、LinterとFormatterそれぞれの有名どころの紹介とその導入方法を記載します。

1. Linter

Pythonで利用者の多いLinterとして「Flake8」と「Pylint」が挙げられます。個人開発、チーム開発に寄らず統一的なコーディングのためにどちらかを導入することを推奨します。

1.1 Flake8 (推奨度:★★★)

Flake8は「pycodestyle」「pyflakes」「mccabe」の3つのLintツールが入ったラッパーです。

  • pycodestyle:コードがPEP8に準拠しているかチェック
  • pyflakes:コードに論理的なエラーがないかをチェック
  • mccabe:循環的複雑度のチェック

これら3つのLinterによりPythonプロジェクトを包括的に静的解析することができます。

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「Flake8」を検索し、インストール
image.png
インストールするだけで自動でFlake8が実行されるようになります。

プロンプトでpipインストール・実行
pip install flake8 # Flake8をインストール

flake8 mypythonfile.py # 特定のファイルに対して実行する場合
flake8 . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

例えばPEP8では1行を最大79文字までに制限することが定められています。なのでFlake8はデフォルトで1行が79文字以上になると警告を表示します。
しかし、プロジェクトによっては最大120文字まで許可したい場合もあると思います。このような場合、Flake8に独自の設定を入れることで一部ルールの緩和や変更を行うことができます。

プロジェクトのルートディレクトリに.flake8ファイルを新規作成し、設定したい内容を記述します。

.flake8
[flake8]
max-line-length = 120
extend-ignore = E266
exclude = ./.venv
max-complexity = 10

VSCodeのプラグインに設定を反映する

VSCodeのsettings.jsonにPylintの設定を.flake8を参照するよう加筆します。

settings.json
 {
    "flake8.args": [
        "--config=.flake8",
    ],
}

1.2 Pylint (推奨度:★★)

PylintはFlake8よりも少し厳格なLinterでVSCodeのデフォルトに設定されています。
Pylintの面白いところはコードを点数で評価してくれる点です。Pylintは厳格なため全ての警告を解消できればコードとしてとても品質の高いものになります。
Flake8よりも詳細に解析できる反面、プロジェクト規模が大きくなると実行に時間がかかってしまいます。

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「Pylint」を検索し、インストール
image.png
インストールするだけで自動でPylintが実行されるようになります。

プロンプトでpipインストール・実行
pip install pylint # Pylintをインストール

pylint mypythonfile.py # 特定のファイルに対して実行する場合
pylint . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

PylintもFlake8同様に独自の設定を入れることで一部ルールの緩和や変更を行うことができます。PylintはFlake8よりも厳格なため警告を抑止したくなることが多い印象です。

まず.pylintrcファイルを生成します。

pylint --generate-rcfile > ./.pylintrc

生成された.pylintrcファイルに設定を記述します。

.pylintrc
[FORMAT]
max-line-length=120

VSCodeのプラグインに設定を反映する

VSCodeの「settings.json」にPylintの設定を.pylintrcを参照するよう加筆します。

settings.json
 {
    "pylint.args": [
        "--rcfile=.pylintrc"
    ],
}

2. Formatter

「Black」「autopep8」「yapf」のうちのどれかと「isort」を入れておくことを推奨します。

2.1 Black (推奨度:★★★)

「無駄な設定の議論をなくす」をモットーにしたFormatterで、PEP8準拠に加えてBlack独自のコードスタイルにフォーマットされます。
特徴としてはカスタマイズがほとんどできず※、独自のコードスタイルが強制される点です。例えばPEP8ではどちらでも良いとされている'"の使用がblackでは"に強制されます。
よってPEP8よりもう一段制限が強い規則を適用すると言い換えることもできるかもしれません。
改行の方法など開発者の流儀に合わない可能性もある半面、複数の開発者がいる状況において私見が入る余地なくツールで統一される方が考慮することも少なく楽です。
※1行の最大文字数やフォーマット適応除外ファイルの設定など最低限の設定は可能

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「Black Formatter」を検索し、インストール
image.png
settings.jsonに以下を加筆します。"editor.formatOnSave": trueにすることでファイルの保存時に自動でフォーマットが実行されるようになります。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "ms-python.black-formatter",
          "editor.formatOnSave": true,
    },
}
プロンプトでpipインストール・実行
pip install black # blackをインストール

black mypythonfile.py # 特定のファイルに対して実行する場合
black . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

Blackはカスタマイズできる項目が少ないですが一部カスタマイズ可能です。
最大文字数などLinter側で独自設定を入れている場合はFormatter側にも同じ設定を入れておきましょう。
プロジェクトのルートディレクトリにpyproject.tomlファイルを作成し、設定を記述します。

pyproject.toml
[tool.black]
line-length = 120

VSCodeのプラグインに対して設定する

VSCodeのsettings.jsonにyapfの設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "ms-python.black-formatter",
          "editor.formatOnSave": true,
    },
+   "black-formatter.args":["--config", "pyproject.toml"],
}

2.2 autopep8 (推奨度:★★)

PEP8に準拠したスタイルのフォーマットを自動で行ってくれます。※
特徴は最低限にフォーマットを行うことです。他のFormatterに比べて強制力が弱く、元のコードに対して変更を最低限に抑えてフォーマットします。
※一部対応していないPEP8ルールがあります。(詳細)

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「autopep8」を検索し、インストール
image.png
settings.jsonに以下を加筆します。"editor.formatOnSave": trueにすることでファイルの保存時に自動でフォーマットが実行されるようになります。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "ms-python.autopep8",
          "editor.formatOnSave": true,
    },
}
プロンプトでpipインストール・実行
pip install autopep8 # blackをインストール

autopep8 mypythonfile.py # 特定のファイルに対して実行する場合
autopep8 . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

autopep8は最大文字数や無視したいPEP8のルールの設定などカスタマイズ可能です。
最大文字数などLinter側で独自設定を入れている場合はFormatter側にも同じ設定を入れておきましょう。
プロジェクトのルートディレクトリにpyproject.tomlファイルを作成し、設定を記述します。

pyproject.toml
[tool.autopep8]
max_line_length = 120
ignore = "E266"

VSCodeのプラグインに設定を反映する

VSCodeのsettings.jsonにautopep8の設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "ms-python.autopep8",
          "editor.formatOnSave": true,
    },
+   "autopep8.args":["--config", "pyproject.toml"],
}

2.3 yapf (推奨度:★★)

かのGoogle大先生が開発したオープンソースのFormatterです。
特徴は整形美により重きを置いたフォーマットを行うことです。PEP8準拠はもちろん、GoogleやFacebookといった別のコーディング規約に準拠させることも可能で、ユーザ独自のコーディング規約に準拠させることもできます。
なので独自にカスタマイズしたスタイルをプロジェクトに適応したい場合はおすすめです。

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「yapf」を検索し、インストール
image.png
settings.jsonに以下を加筆します。"editor.formatOnSave": trueにすることでファイルの保存時に自動でフォーマットが実行されるようになります。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "eeyore.yapf",
          "editor.formatOnSave": true,
    },
}
プロンプトでpipインストール・実行
pip install yapf # yapfをインストール

yapf mypythonfile.py # 特定のファイルに対して実行する場合
yapf . # 全てのファイルに対して実行する場合

(Option) 独自の設定を適応する

yapfはカスタマイズ性が特徴なのでもちろん他のFormatter同様にカスタマイズ可能です。
最大文字数などLinter側で独自設定を入れている場合はFormatter側にも同じ設定を入れておきましょう。
プロジェクトのルートディレクトリにpyproject.tomlファイルを作成し、設定を記述します。
カスタマイズ項目が沢山あるので、詳細は公式ドキュメントを参照してください。

pyproject.toml
[tool.yapf]
column_limit = 120 # 1行の最大文字数を120文字に設定

VSCodeのプラグインに設定を反映する

VSCodeのsettings.jsonにyapfの設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "eeyore.yapf",
          "editor.formatOnSave": true,
    },
+   "yapf.args":["--style","pyproject.toml"],
}

2.4 isort (推奨度:★★★)

isortはpythonのimport文の順序フォーマットしてくれます。
まずimport文を標準ライブラリ→その他ライブラリ→ローカルなアプリケーション/ライブラリにグループ化し、グループ間を空白行で分離します。その上で各グループ内をアルファベット順に並び替えを行ってくれます。
開発者によってバラバラになってしまうimport文の記述を統一できるのでisortは必須で入れておきたいですね。

インストール・実行方法

VSCodeでインストール・実行

拡張機能から「isort」を検索し、インストール
image.png
settings.jsonに以下を加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "black-formatter",
          "editor.formatOnSave": true,
+         "editor.codeActionsOnSave": {
+              "source.organizeImports": "explicit"
+              }
    },
    "black-formatter.args":["--config", "pyproject.toml"],
}
プロンプトでpipインストール・実行
pip install isort # isortをインストール

isort mypythonfile.py # 特定のファイルに対して実行する場合
isort . # 全てのファイルに対して実行する場合

※FormatterにBlackかyapfを採用している場合

FormatterにBlackを使用している場合やyapfでGoogleをベーススタイルにしている場合はprofileを指定する必要があります。
pyproject.tomlファイルに設定を記述します。

pyproject.toml
[tool.isort]
profile = "black" # yapfでGoogleをベーススタイルにしている場合は"google"

VSCodeのプラグインに設定を反映する

VSCodeのsettings.jsonにisortの設定をpyproject.tomlを参照するよう加筆します。

settings.json
{
    "[python]": {
          "editor.defaultFormatter": "black-formatter",
          "editor.formatOnSave": true,
          "editor.codeActionsOnSave": {
              "source.organizeImports": "explicit"
              }
    },
    "black-formatter.args":["--config", "pyproject.toml"],
+   "isort.args":["--settings-file", "pyproject.toml"]
}

参考文献

30
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?