Pythonのコードを改善するためのツールについて一通り試してみました。各ツールのインストール方法や使い方については Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ! - Sider Blog に詳細にまとまっているのでおすすめです。
サンプルコード
以下のサンプルコードを対象に、各ツールの出力を確かめてみます。
import time
import sys
import fractions
def func1(varA,varB):
'''return sum of a and b'''
varC = 42
return (varA + varB)
print(func1(fractions.Fraction(1, 2), fractions.Fraction(1, 3)))
3 + 5
sys.exit(0)
このスクリプトをsample.py
という名前で保存したのち、以下のスクリプトで実験をしました。各ツールはすべてデフォルトです。
for name in pycodestyle \
pydocstyle \
pyflakes \
flake8 \
pylint
do
echo "================="
echo ${name}
echo "================="
echo "version:" $(${name} --version)
${name} sample.py
echo ""
done
各ツールの紹介
出力は以下のとおりです。空白行やスペースの不足が指摘されています。
version: 2.0.0
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:5:15: E231 missing whitespace after ','
- 用途:docstring専用のスタイルチェック
- PEP 257で規定されているdocstring (moduleや関数の最初に記される、
"""
と"""
で囲まれたコメントのこと)の書き方に違反する箇所を見つけてくれる。
- 詳細
出力は以下のとおりです。docstringに関するエラーのみが指摘されています。
version: 2.1.1
sample.py:1 at module level:
D100: Missing docstring in public module
sample.py:5 in public function `func1`:
D300: Use """triple double quotes""" (found '''-quotes)
sample.py:5 in public function `func1`:
D400: First line should end with a period (not 'b')
sample.py:5 in public function `func1`:
D403: First word of the first line should be properly capitalized ('Return', not 'return')
- 用途:エラー解析
- 詳細
- ソースファイルを解析して、importしたけど使っていないモジュールや、未使用の変数などを報告。
- pycodestyleとは違い、コードのスタイルについては分析しない。
- 高速さに重点を置く。Pylintよりも高速。
- 正しいコードを過ってエラーと報告しないように細心の注意が払われている。
- 解析はファイル単位で行われるので、importで読み込むファイルにまたいだ解析はできない。
- もっと詳しい分析が必要な場合は、Flake8を使う。
出力は以下のとおりです。未使用のimport文、未使用の変数が報告されています。
version: 1.2.3
sample.py:1: 'time' imported but unused
sample.py:7: local variable 'varC' is assigned to but never used
- 用途:スタイルチェック + エラー解析 + 複雑度チェック
- 詳細
出力は以下のとおりです。ちょうど出力がpycodestyleとpyflakesの和になっていることがわかります。
version: 2.6.2 (pycodestyle: 2.0.0, mccabe: 0.5.3, pyflakes: 1.2.3) CPython 3.6.4 on Windows
sample.py:1:1: F401 'time' imported but unused
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:5:15: E231 missing whitespace after ','
sample.py:7:5: F841 local variable 'varC' is assigned to but never used
- 用途:スタイルチェック + エラー解析
- 詳細
- 老舗のツール。effective pythonで推されていた。
- Plugin機能がある。
出力は以下のとおりです。flake8では報告されなかった、変数名の規則違反(varA
など)や、意味のない文('3 + 5')が報告されています。
最終行にこのコードの得点が表示されるのが面白いです。この場合10点満点中0点という意味です。さらには負の点数になることもあります。
No config file found, using default configuration
Python 3.6.4 |Anaconda custom (64-bit)| (default, Jan 16 2018, 10:22:32) [MSC v.1900 64 bit (AMD64)]
No config file found, using default configuration
************* Module sample
C: 5, 0: Exactly one space required after comma
def func1(varA,varB):
^ (bad-whitespace)
C: 8, 0: Unnecessary parens after 'return' keyword (superfluous-parens)
C: 1, 0: Missing module docstring (missing-docstring)
C: 5, 0: Argument name "varA" doesn't conform to snake_case naming style (invalid-name)
C: 5, 0: Argument name "varB" doesn't conform to snake_case naming style (invalid-name)
C: 7, 4: Variable name "varC" doesn't conform to snake_case naming style (invalid-name)
W: 7, 4: Unused variable 'varC' (unused-variable)
W: 12, 0: Statement seems to have no effect (pointless-statement)
W: 1, 0: Unused import time (unused-import)
------------------------------------------------------------------
Your code has been rated at 0.00/10 (previous run: 0.00/10, +0.00)
flake8のプラグインを別途インストールすることで、flake8にルールを追加することが可能です。pip search flake8-
するとわかるのですが、大量のプラグインが存在しています。ここでは2つだけ紹介します。
- 用途:Flake8にOpenstack社のルールを追加するプラグイン
- 詳細
pip install hacking
したあとにflake8を呼び出すと、flake8に、Openstack社が独自に追加したルールが追加される
出力は以下のとおりです。H
で始まる行が、flake8に追加された検出された項目になります。この例だとimport文の順番がアルファベット順になっていなかったことで怒られています。
version: 2.6.2 (pycodestyle: 2.0.0, mccabe: 0.5.3, ProxyChecker: 0.0.1, hacking.core: 0.0.1, pyflakes: 1.2.3) CPython 3.6.4 on Windows
sample.py:1:1: F401 'time' imported but unused
sample.py:2:1: H306 imports not in alphabetical order (time, sys)
sample.py:3:1: H306 imports not in alphabetical order (sys, fractions)
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:5:15: E231 missing whitespace after ','
sample.py:7:5: F841 local variable 'varC' is assigned to but never used
- 用途:Flake8に
pydocstyle
のルールを追加するプラグイン
- 詳細
pip install pydocstyle
したあとにflake8を呼び出すと、flake8に、pydocstyle
のルールが追加される
出力は以下のとおりです。D
で始まる行がdocstringに関する報告です。
version: 2.6.2 (pycodestyle: 2.0.0, mccabe: 0.5.3, pyflakes: 1.2.3, flake8-docstrings: 1.3.0, pydocstyle: 2.1.1) CPython 3.6.4 on Windows
sample.py:1:1: D100 Missing docstring in public module
sample.py:1:1: F401 'time' imported but unused
sample.py:5:1: D300 Use """triple double quotes"""
sample.py:5:1: D400 First line should end with a period
sample.py:5:1: D403 First word of the first line should be properly capitalized
sample.py:5:1: E302 expected 2 blank lines, found 1
sample.py:5:15: E231 missing whitespace after ','
sample.py:7:5: F841 local variable 'varC' is assigned to but never used
サンプルコードの修正例
すべてのエラーや警告が消えるまで修正したのが以下のコードです。良いコードになったでしょうか?
"""Sample for hatena diary."""
import fractions
import sys
def func1(var_a, var_b):
"""Return sum of a and b."""
return var_a + var_b
print(func1(fractions.Fraction(1, 2), fractions.Fraction(1, 3)))
sys.exit(0)
その他のツール
型ヒントのためのツールです。自分はまだ理解できていません。
- 用途: Optional Static Typing for Python
- Python 3.6に導入された型ヒントを使っている人向けのツール。型の誤りを静的に解析する。
- 用途:スタイルチェック + エラー解析
- 詳細
- Python 2.x系が対象。開発が止まっているようなので今から使う理由はないでしょう。
個人的な結論
- まずはflake8をデフォルトで使う
- flake8で足りないところがあれば、Pylintを併用するか、flake8の適当なプラグインを見つけて導入する
flake8についてはこちらの記事により詳しい使い方をまとめました。
参考
- Pythonのスタイルガイドとそれを守るための各種Lint・解析ツール5種まとめ! - Sider Blog
- pep8(現pycodestyle), pyflakes, flake8, hacking, pylintの使い方について詳細に記述されています。
- About style guide of python and linter tool. pep8, pyflakes, flake8, haking, Pylint.
- Python の Lint (文法チェッカ) まとめ - flake8 + hacking を使う -
- 4 Best open source Python static analysis tools as of 2018 - Slant
- Pylint, flake8, mypy, pyflakesに対する人気投票
- 5 Best Python code linters as of 2018 - Slant
- Any advantages of Flake8 over PyLint? : Python
- Code Style — The Hitchhiker's Guide to Python
- pylint や pyflakes がパースできないような変なコードはそもそも避けるべきという話題
- Flake8 のプラグイン機構についてのお話 - SideCI TechBlog