- 近年のAI開発のトレンドを受けて、本格的にPythonの学習と利用を始め、今ではそのエコシステムに大きな満足を感じている
- Pythonは以前よりはるかに高速でモダンな言語へと進化しており、Cythonによる性能向上など、その急速な発展を実感している
- uv、ruff、pytest、Pydanticなどの最新の開発ツールやライブラリを自身のワークフローに積極的に導入し、開発生産性を高めている
- 本番環境とJupyterノートブック/スクリプトベースの開発との違いを縮めるためのプロジェクト構成や自動化の仕組みも適用している
- GitHub Actions、Dockerなどを活用して、CI/CD、テスト、インフラ管理を効率的に構築している
I’m Switching to Python and Actually Liking It 要約
なぜPythonに乗り換えたのか
- AI中心の開発環境では、Pythonが事実上の標準言語として定着している
- 以前は単純なスクリプト作成にしか使っていなかったが、最近ではRAG、エージェント、生成AIなどの**「実運用向けアプリ」を作るために本格的に使う**ようになった
- その過程で、Pythonのエコシステムが以前と比べて大きく進化していることを実感した
Pythonの強み3つ
- 豊富なライブラリとツールのエコシステム: データ処理、分析、Web、AIに特化
- Cythonなどによる性能改善: コンパイルベースの最適化が可能
- 改善された構文の可読性:
__init__、__new__ のようなレガシー構文は隠され、より直感的な構文が提供されている
プロジェクト構成(Monorepoベース)
主なツールと設定
-
uv
- Astralが提供する最新のPythonパッケージマネージャー兼ビルドツール
- 依存関係管理、仮想環境の作成、プロジェクト初期化など、ほとんどの作業を高速に処理する
pyproject.toml が中核となる設定ファイルで、すべてのメタデータと依存関係情報が統合される
uv init、uv add、uv sync コマンドで素早くプロジェクト環境を構築できる
-
ruff
- 超高速のPythonリンター兼コードフォーマッター
isort、flake8、autoflake などを統合したツール
ruff check、ruff format でリンティングと自動修正を行う
- PEP 8コーディングスタイルガイドを標準サポート
-
ty
- Astralが作ったPython向け静的型チェッカー
typing と組み合わせて静的解析を行い、初期段階のバグ防止に効果的
- 開発初期段階でありながら、安定して使える水準にある
-
pytest
- 単体テストと拡張可能なテスト環境を提供する代表的なPythonテストフレームワーク
- シンプルなファイル命名規則と1行のコマンドで、すぐに統合テストを実行できる
test_*.py でテストを構成し、uv run pytest で実行
- 簡潔な構文、豊富なプラグインエコシステム
-
Pydantic
- データ検証および環境設定管理ライブラリ
.env 環境変数ベースの設定読み込みと型検証
BaseSettings クラスを通じてAPIキーやDB URLなどを安全に管理
-
MkDocs
- Pythonプロジェクトの静的Webサイトとドキュメント生成を手軽に支援
- オープンソースプロジェクト風の洗練されたデザインを素早く適用可能
- GitHub Pagesとの連携も容易
-
FastAPI
- 高速なRESTful API構築フレームワーク
- 自動検証とドキュメント化、高速な性能、Pydanticとの容易な統合が強み
- StarletteおよびPydanticベースで、高い型安全性と性能を提供
-
Dataclasses
- Python標準機能としてデータ中心のクラスを手軽に定義できる
- 特殊メソッドの自動生成により、ボイラープレートコードを大幅に削減
バージョン管理と自動化
-
GitHub Actions
project-api と project-ui それぞれに対して個別のCIパイプラインを構成
- さまざまなOSでCIパイプラインを構築するのに最適化されたワークフローを提供
- Dockerベースのテスト環境により、本番と同一の環境でテストを実施できる
-
Dependabot
- 依存関係の自動更新とセキュリティパッチ管理を自動化する
-
Gitleaks
- 機密情報(パスワード、APIキーなど)の漏えい防止ツールとして、gitコミット前にセキュリティ検査を実施する
-
Pre-commit Hooks
- コミット前の自動リンティング、フォーマット、セキュリティ検査のためのツール
- ruff、gitleaksなどと併用して、コードの一貫性と品質を維持する
インフラ自動化
-
Make
make test、make infrastructure-up などのコマンドで一貫した開発ワークフローを支援
- プロジェクトルートと
project-api にそれぞれMakefileが存在する
-
Docker & Docker Compose
project-api、project-ui をそれぞれコンテナとして分離して実行
docker compose up --build -d 1行でアプリ全体を起動可能
Dockerfile にはuvのインストール、FastAPIアプリの実行コマンドが含まれる
まとめ
- このように、最新のPython開発環境では効率的で堅牢な本番ワークフローを構築できる
- AI、データ、Web開発など幅広い分野で、Pythonエコシステムの成長とツールの進化から多くの恩恵を受けられる
- モノレポ構成、自動化ツール、リンターと型チェッカー、即時に使えるテスト環境、ドキュメント化、インフラオーケストレーションまで、ひとつの統合された開発文化を実現できる
6件のコメント
Pythonはライブラリやフレームワークが豊富な一方で、パッケージのバージョン管理があまりうまくなく、競合が起こりやすいのが欠点です。
昔のJavaと長所・短所の傾向が似ています
本文にも出てきた
uvは本当に優れものです。速いのはもちろん、バージョンや依存関係の管理も npm みたいにうまくやってくれるので、uvに定着しつつあります。それでも最近は、uv や poetry を通じてバージョン管理や競合の問題はほとんど解消されたようです
Reactやこのような部分まで含めて、エコシステム全体をカバーするのにも適していますか?
Reactとの直接的な連携は、言語が異なるため難しい部分もありますが、何を実現したいかによっては可能な部分もあると思います。
個人的には、Pythonによるフロントエンド開発はあまり活発ではない分野だと考えています。
Hacker News の意見
コードで環境変数が欠けているときに「YOUTUBE_API_KEY または YOUTUBE_CHANNEL_ID がありません」と OR でまとめて表示するやり方は、わざわざ OR を使う必要がない場面でユーザーを困らせるだけ。各値を個別にチェックして、何が欠けているのかを明確に伝えるほうが、はるかに良いユーザー体験になる。開発時間の差もほとんどないので、そうするのを勧めたい
細かいところまで執拗に掘る話ではあるけれど、こういうケースは := 演算子(ウォルラス演算子)を使うのにちょうどいいと思う。たとえば
if not (API_KEY := os.getenv("API_KEY")):のようにその場で書ける。個人的には内部ツールではos.environ["API_KEY"]で KeyError をそのまま出させている。これも十分わかりやすいと思うさらに言えば、条件を一つずつ確認して、ひとつでも欠けていたら全部まとめて知らせるほうがずっとよいと思う。ある変数が欠けているせいでプログラムを走らせ、その次にまた別の変数エラーを見るという面倒を減らせる。状況によってはどうしても煩雑になることもあるが、できる限り一度で見せるのがよい
環境変数を全部取得して、その中で欠けているものをまとめて報告する方法がいちばんよい
boolean フラグを使って最後に一度だけ
exit(1)する方法もある。こうすれば欠けている環境変数を一度にすべて表示できるexit("Missing ...")のようにメッセージをそのまま表示しつつ、コード 1 で終了することもできるプロジェクト構成を自動生成するツールを探しているなら cookiecutter を勧める。自分がよく使うテンプレートはいくつかあって、python-lib、click-app、datasette-plugin、llm-plugin などがある。使い方は次のとおり:
uvx cookiecutter gh:simonw/python-libRuby で baker というものを作った。baker はテンプレート repo をコピーするのではなく、やるべき作業リスト(命令形のステップ一覧)を作り、手動作業(API key を取得して設定するなど)と自動作業(
uv initなど)を混在させられる。Markdown 記法に Ruby の文字列補間や bash も使える。yml ベースの config にすっかりうんざりしていたので作ることになった最近注目されているのは Copier というツール。詳しくは copier ドキュメント を参照
新規プロジェクトのセットアップはむしろ楽しむほうだ。こういうものをわざわざ自動化したいとは思わない
こうした構成自動化ツールは、実際いまのエージェントベース LLM 開発ワークフローにもぴったり合う領域だと思う
「Python は Unix の大半に標準搭載されているから、より人間にやさしい」という評価はやや楽観的な見方だ。
import jsonを超えたあたりから、すぐに virtualenv 地獄に落ちることになる。Python 3.13.x 環境で Ubuntu 22.04 や 24.04、Rocky 9 などで動かすなら、結局 venv、コンテナ、バージョンマネージャーは必須になるimport jsonのような標準ライブラリでさえ、組み込みでない言語なら別途インストールが必要だが、Python は標準ライブラリのおかげで初期の生産性が高い。もちろん大規模プロジェクトでは標準ライブラリだけでは足りないが、実際に標準ライブラリだけで複数の実運用コードを配布してきたし、配布やセキュリティ管理の問題も起きていない。venv の管理も昔ほど難しくなく、パッケージマネージャーも進歩している半分冗談で言っている持論のひとつだが、Docker/コンテナがここまで早く広まった理由の半分は、Python の依存地獄を乗り越えられるようにしてくれたからだと思う。自分の最初の Python 体験は 2012 年にサーバーへ Python サービスを導入することだったが、依存地獄、venv コマンド、扱いづらい環境設定、とにかくひどかった。pip、brew、macOS 環境でもひたすら苦労し、Python を見るだけで避けていた。でも最近は uv のおかげで、初心者の立場でも Python がずいぶんましになったと感じる。
uv init、uv add、uv runだけでも十分だvirtualenv は常に使うべきだと思う。結局はひとつのディレクトリにすぎないし、いまは pip でシステム全体にインストールしようとすると警告も出るなど、昔ほど難しくない
virtualenv や container は必ず使ったほうがいい。扱いが難しく感じられても、更新やライブラリのバージョンアップでシステム全体に影響を与える事態を避けられる
昔はシステムに Python2 だけが標準で入っていることが多く、システム自体がその Python2 に依存している場合もあったので、むしろ危険だった
Python は同時に冗長でもあり、足りなくもあると感じる。ちょっとしたことをやろうとすると依存関係を 500 個入れるか、あるいはごく些細なことでも数十行から多ければ数百行までコードが増えてしまう。だから Python は不要な苦労が多すぎて避けてしまう。Perl ならもっと速く簡潔に片付けられるので Perl を好む。Python は何かの仕事をするためというより、プログラミングのためのプログラミングになりがちだ
自分は依存関係のないプロジェクトもたくさん作っている。標準ライブラリと単一ファイルだけでも本当に多くのことができる。Python さえ入っていれば curl でそのまま落として実行できる。たとえば 2000 行の家計管理 CLI ツールがあるが、plutus は 12 個ほどの標準モジュールしか使っていない。コードの約 25% は argparse でコマンドをパースする部分だ。パラメータごとに 1 行ずつ置くような形で、明確に書くのが好きだ
Perl が Python より速くて強力だと言っていたが、具体的にどういう例があるのか気になる
Python はデータ構造を入れ子にするとき、あまり頭を使わずそのまま書ける点が楽だ。リストの中にタプルや辞書などを自由に混在させられ、統一された文法でアクセスできる。Perl はたしかにもっと賢くて面白いが、そのぶん頭の中がこんがらがりやすく、自分にはあまり向いていない。Python は退屈ではあるが、5 年後に見返しても理解できるほど明快さが大きい
Python は標準ライブラリだけでも十分実用になると思う
自分はモノレポ構成の支持者だが、以前いた会社ではこの方式のせいで超巨大で肥大化した構造になり、他チームのコードを誤って触ってしまうのを恐れて誰も手を出さなくなったことがある。問題の核心はレポ自体ではなく、
requirements.txtをレポ全体でひとつに管理していたことや、ビルドスクリプトが絡み合っていたことのほうが大きい。理論上は一度だけ依存関係を更新すれば、すべてのコードが最新パッチで安全になるはずだが、現実には誰もそれに触れなかった。モノレポは、組織が非常に NIH(Google のように何でも自前で作る傾向)な場合にだけうまく回る。この経験のせいで、各サービスが組織内のチーム構造と一致するマイクロサービス構成を、むしろ高く評価するようになった。Conway's law も参照するとよいPython は、自分が書いた疑似コードに最も近い形で動く言語だ。頭の中で「これは明らかだ」と通り過ぎる部分ごとに、実際にも Python が直感的な抽象化を提供してくれる。数学ベースのバックグラウンドから来たので、とても満足のいくものだった。もちろん今は他の言語も好きだが、それでもまだ魅力がある
ほとんど同じパターンでプロジェクト構成を作っている。あまりに似すぎていて不気味なくらいだ。Python 開発者の生態系が、だんだん似たスタイルへ収束しているのではないかと思う。以前は自分の選択がユニークだと思っていたのに、みんな同じやり方なら自分の自由意志はどこへ行ったのかと思ってしまう。ありふれた赤ちゃんの名前を付ける現象に近くて、独特だと思っていた選択が実は人気第 2 位だった、という感じだ
こういう構成は 10 年前から Python で人気があった。結局のところ、合理的なエンジニアたちが考え抜いた末に、このパターンへ自然に集まっていくのだと思う
人のエゴがまるでパイロット波の量子波のように、あらゆるスペクトラムに広がっていて、そこから存在へと変化していく感じがする。becoming-being、思わず笑ってしまう
他の人も Python を好きになったのを見ると、うれしく感じる。自分はもともと Ruby を好んでいたが、顧客の要望でやむを得ず Python を使うことになった。昔は Ruby がかなり遅かったが、無理やり Python を覚えていくうちに次第に慣れ、今ではそれなりに楽しんでいる。Make の使い方については少し異論があって、依存関係をまったく使わないなら、case 文の入ったスクリプトと大差ない。半分冗談だが、最近の世代が Make に慣れていないのを見ると物寂しい。自分の時代はなあ、という気分だ
Ruby のほうが文法はずっときれいだ。インデントだけでスコープを区切る Python は自分の好みではない
最初は case 文入りのスクリプトから始めたが、結局フラットな Makefile に進化した。Makefile のほうがより標準的で、場当たり的なスクリプトより把握しやすい
Dataclass と Pydantic BaseModel のどちらを使うべきか気になる。すでに Pydantic を使っているなら、全部 Pydantic に統一してしまってもいいのではないかと思うが、あえて Dataclass を使う理由があるのか悩む
attrs プロジェクトで非常によく整理された比較記事がある。attrs 公式比較 があり、もちろん多少のバイアスはあるだろうが、論理的な根拠は十分だと思う。あと このブログ も参考になる
Dataclass はネストしたオブジェクトの検証をサポートしていない。だから、単純に関数の引数受け渡し用のフラットな構造には dataclass を使うほうがよい。引数を大量にリストで受けるより明確だ
生成時のデータ検証のせいで、性能低下の問題がある。msgspec のように、もっと軽量で高速な代替もある
検証やシリアライズが特に不要なら、Pydantic はむしろ無駄なオーバーヘッドだ。自分の原則は、シリアライズが必要なら Pydantic、そうでなければ dataclass だ
TypeAdapter(MyDataclass)のように既存の dataclass をそのまま使えるのだから、わざわざ Pydantic モデルを別に作る理由があるのかと思う最近はむしろ Python ではなく、別の言語へ移って満足している。自分の Python に対する考えは この記事 にまとめてある。次にまた Python を使う機会が来たら、uv、ruff、ty のようなものをぜひ試してみたい