yynsmk's tech blog

何でもできる=何にもできない

【VS Code】BlackとFlake8を使ってきれいなPythonコードを書く!!

はじめに

チーム開発をしていると、コードのフォーマットや書き方の癖が人によって違うことが多々あります。
その違いをなくすためのツールがリンタやフォーマッタです。
これらを導入することで、チーム内でのコーディングのルールを統一できるだけでなく、コードもきれいになります。

ここでは、最近話題のVS CodeにFlake8とBlackを導入する方法を説明します。
似たようなツールは他にもありますが、Flake8とBlackを組み合わせて使うのが個人的に気に入っています。

Flake8とBlack

Flake8

pythonにはpep8というコーディング規約があります。
Flake8はコードがこの規約通りに書けているか、シンタックスエラーがないかなどをチェックしてくれるツールです。

Flake8は以下のツールのラッパーです。
pyflakesは論理的なエラーを、pycodestyleはpep8に沿っているかを、mccabeは循環的複雑度をチェックします。

Black

Flake8はコードのチェックには非常に便利ですが、エラーの修正まではしてくれません。
このエラー修正を自動でやってくれるのがBlackです。
Blackはpep8に準拠しているので、pep8に関するエラーを自動で修正してくれるだけでなく、改行の仕方やクォーテーションの使い方まで統一してくれます。
また、Blackには設定項目がほとんどないため、導入がとても簡単です。

Flake8とBlackの詳細についてはドキュメントを見てください。
github.com flake8.pycqa.org

BlackとFlake8のインストール

まず、Flake8とBlackを導入するPythonのプロジェクトを作成します。
ホストが汚れるのが嫌なので仮想環境を作ります。
環境さえ作れればここは何でも大丈夫です。

$ python3 -m venv venv
$ source venv/bin/activate

環境ができたら、pipでBlackとFlake8をインストールします。

$ pip install black flake8

pipenvを使う場合は以下を参考にしてみてください。 www.m3tech.blog qiita.com

VS Codeの設定

まず、「Python ms-python.python」という拡張機能をインストールして有効にします。
次に、ワークスペースの設定から右上の{}を押して.vscode/settings.jsonを開きます。

f:id:b_murabito:20190703013856p:plain

ここに、以下を加えます。
デフォルトのリンタのpylintはOFFにしておく必要があります。 また、Blackが定める一行あたりの文字数は88文字で、Flake8は79文字です。
この違いをなくすために、12行目でFlake8の最大文字数を88文字に変えています。 細かい設定等は、python.linting.flake8Argspython.formatting.blackArgsで変えられるので、ドキュメントを見つつ、自分好みにしましょう。

{
  // pythonの環境設定
  "python.pythonPath": "venv/bin/python",
  "files.watcherExclude": {
    "**/venv/**": true
  },

  // リンタの設定
  "python.linting.pylintEnabled": false,
  "python.linting.flake8Enabled": true,
  "python.linting.lintOnSave": true,
  "python.linting.flake8Args": [
    "--max-line-length",
    "88",
    "--ignore=E203,W503,W504"
  ],
  // フォーマッタの設定
  "python.formatting.provider": "black",
  "editor.formatOnSave": true,
  "editor.formatOnPaste": false
}

動作確認

以下のコードを例にして動作を確かめます。

def foo():
    print(
                "Hello"
        "World"
        )

上のコードを保存した時に自動できれいなコードに変わればOKです。

def foo():
    print("Hello" "World")

ちなみに今はエラーは出ないですが、Flake8のエラーは以下のような感じで出ます。

f:id:b_murabito:20190703112812p:plain

参考サイト

blog.hirokiky.org