Pythonのプロジェクト管理とデバッグに無駄にした時間について考える悲しいプログラマー
私は、Pythonを使用して作業している企業やプロジェクトで、いくつかの点に気づきました。それらは、イライラするものであり、メンテナンスが難しく、古くなっています。早速見ていきましょう。
requirements.txtの代わりにPyProject.tomlを使用する
やめましょう。README.mdに「pip install -r requirements.txtで依存関係をインストールする」と書くのはやめましょう。pipでできますか?はい。そうすべきですか?いいえ。requirements.txtは偶然の標準です。pyproject.tomlを使用するだけです。それは理にかなっており、pipはそれを理解し、その中で依存関係の開発やグループを定義できるので、「dev-requirements.txt」やたくさんのCICDパイプラインルールを使い始める必要はありません。
- 参照 https://www.reddit.com/r/learnpython/comments/1bmxe6i/whats_the_difference_between_pyprojecttoml/
PoetryやUVのようなPythonバージョンとプロジェクトマネージャーを使用する
私はUVが好きですが、Poetryも好きです。どちらもpyproject.tomlファイルを読み取り、依存関係、ビルド、サンドボックス内のアプリケーションの実行、Pythonのバージョン管理などを処理します。これらのツールについて読むのに1時間かかりますが、頭痛を和らげてくれるでしょう。
最低限、venvのような仮想環境を使用して、グローバルな依存関係の問題を回避してください。
また、UVはpipよりもはるかに高速に依存関係をインストールします。
型ヒントを使用する
型ヒントは、可読性に優れており、ruffやmypyなどのリンターがコードで何が起こっているのかを知るのに役立ちます。同僚もあなたのコードをより良く評価するでしょう。
2年後にあなたのコードを引き継ぐ時、これは理解するのが難しいです。
def do_something(data): for x in data: for y in data[x]: transmute(data[x][y])
もっと分かりやすくしましょう。
def alter_map(data: Map) -> None: """ 2次元マップ内のデータを変更します。直接参照されるオブジェクトを変更します """ for x in map: for y in map[x]: transmute(map[x][y])
関数のすべてのパラメーター、戻り値の型などに型ヒントを追加します。
関数のdocstringにRaisesセクションを追加する
これは、悪いコードを防止したり、何かを強制したりしないので、議論の余地があるかもしれませんが、それでもコードのメンテナンスに役立ちます。
docstringでRaisesと、この関数から発生する可能性のある例外を追加して、驚きを最小限に抑えます。
これは役に立ちます!
from typing import Dict, Any, optional
def query_db(query: SqlQuery) -> Optional[Dict[str, Any]: """データベースを呼び出します Args: ... Raises: ClientException: あなたが間違えました TimeoutException: DBに時間がかかりすぎました ConnectionException: ネットワークに問題があります Returns: クエリからの応答(ある場合)。 """
辞書や多数の関数パラメーターの代わりに、Pydantic Modelsを使用してデータとパラメーターを渡す
変更されないデータの一部で本質的にpropdrillingを行う関数を持つコードを見るのは疲れました。これは、一度検索されて変更されない多くの環境変数を持つデータ処理パイプラインです。Pydanticクラスを定義するだけで、エラー処理、型チェックができ、単一の引数として関数に渡すことができます。
Ruffのようなリンターとフォーマッターを使用する
JavaScriptプロジェクトにはprettierがあり、現時点ではほぼ標準になっています。Pythonでは、Blackのフォーマット標準をコピーしている高速なruffを使用します。見逃したかもしれない一般的な問題もリントしてくれます。このリンティングは、mypyのような静的解析ツールほど詳細ではありませんが、確かに役立ちます。
追加する際は、pyproject.tomlにいくつかのオプトインルールを追加して、コードベースをさらに改善します。
[tool.ruff]
target-version = "py12"
[tool.ruff.lint]
extend-select: [ 'D', #pydocstyle 'E', 'W', # pycodestyle 'F', #pyflakes 'I', # sort imports 'UP', #pyupgrade "RUF", # ruff dev's own rules "SIM", # pyflakes simplicity "C90", # more complexity rules
]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.lint.isort]
combine-as-imports = true
split-on-trailing-commas = false
ここに追加できるものは多数あります。しかし、アラカルトです。
unittestよりもPytestを使用する
変換するのが理にかなっている場合は、unittestではなくpytestを使用します。pytestのフィクスチャは非常に役立ち、構成可能です。
プロジェクトにこれを忍び込ませることができる熱いテイク
- 組み込みのjsonライブラリの代わりにorjsonを使用する
- 文字列の連結や.format、%sフォーマット文字列の代わりに、常にf文字列を使用する
- os.pathの代わりにpathlibを使用する
- argparseやsys.argvを使用する代わりにclickを使用する
- Python 3.8+にアップグレードする
「Stop making your python projects like it was 15 years ago…」より翻訳された記事です。