この記事の対象読者
- Pythonを「とりあえず動かせる」けど、中身をちゃんと理解していない方
-
pip installは日常だが「なぜそれで動くのか」を説明できない方 - 他言語(JavaScript、Java、C等)を触ったことがあり、Pythonとの違いを整理したい方
- AI/ML分野でPythonを使い始めたが「なぜPython一択なのか」を知りたい方
この記事で得られること
この記事を読むと、以下のことが理解できます:
- Pythonの「正体」— CPythonとは何か、コードが実行される仕組み
- 「遅いのに最強」という矛盾の正体 — GILとC拡張の関係
- 動的型付け・メモリ管理・バイトコードなど「裏側」の仕組み
- pip / venv / conda が存在する「理由」と使い分け
- AI/MLでPythonが覇権を握った技術的背景
この記事で扱わないこと
- Pythonの文法入門(
for文の書き方、リスト内包表記の使い方など) - Django / Flask 等のWebフレームワーク詳細
- Pythonのバージョン間差異の網羅的比較
本記事ではPython 3.12〜3.13系を前提としています。Python 2系には触れません。
本記事の比喩について
この記事では、Pythonのエコシステム全体を世界最大の公共図書館に見立てて解説します。
| Python の概念 | 図書館での対応物 |
|---|---|
| CPython(インタプリタ) | 司書 — あなたのリクエストを読み取り、実行する人 |
| ソースコード(.py) | 利用者が書いた「リクエスト用紙」 |
| バイトコード(.pyc) | 司書が作る「要約メモ」— 次回は素早く対応できる |
| pip / PyPI | 蔵書管理システムと巨大書庫 — 40万冊以上の本がある |
| venv(仮想環境) | 個室の閲覧スペース — 他の利用者と本が混ざらない |
| GIL | 受付カウンターが1つしかないという制約 |
| 動的型付け | 本にジャンルラベルを貼らない方式 — 中身を開いて判断する |
| 参照カウント(メモリ管理) | 貸出カード — 誰も借りていない本は書庫に戻す |
この比喩を頭の片隅に置きながら読み進めてください。
1. Pythonの「正体」— あなたが動かしているのは何なのか
1.1 「Python」は言語仕様であり、実装ではない
多くの人が見落としている事実がある。「Python」とは言語仕様(文法とルール)の名前であり、それを実際に動かすプログラム(実装)は複数存在する。
図書館の比喩で言えば、「Python」とは図書館の運営マニュアルだ。そのマニュアルに基づいて実際に図書館を運営する「司書」は何人もいる。
| 実装名 | 言語 | 特徴 |
|---|---|---|
| CPython | C言語 | 公式リファレンス実装。python コマンドで動くのはほぼこれ |
| PyPy | Python(RPython) | JITコンパイラ搭載で高速。CPythonの数倍速いケースも |
| Jython | Java | JVM上で動くPython。Java資産との連携用 |
| IronPython | C# | .NET上で動くPython |
| MicroPython | C言語 | マイコン・IoT向けの超軽量実装 |
| GraalPy | Java | GraalVM上の新しい実装 |
あなたが python --version で確認できるPythonは、99%の確率でCPythonだ。
# 実装を確認する方法
python -c "import platform; print(platform.python_implementation())"
# 出力例: CPython
「Pythonが遅い」という話題の大半はCPythonの特性を指しています。PyPyに切り替えるだけで劇的に速くなるケースもあるため、「Python = 遅い」は正確ではありません。
1.2 インタプリタという「司書」の仕事
CPythonはインタプリタだ。図書館の司書のように、あなたが書いたリクエスト用紙(.pyファイル)を一行ずつ読み取って実行する。
ただし「一行ずつ」というのは半分正確で半分不正確。実際にはCPythonは2段階で動いている。
-
コンパイルフェーズ:
.pyファイルをバイトコード(.pyc)に変換する - 実行フェーズ: バイトコードをPython仮想マシン(PVM)が解釈・実行する
図書館の司書は、最初にリクエスト用紙を読んで「要約メモ」を作る。次回同じリクエストが来たら、要約メモから素早く対応できる。__pycache__ フォルダに溜まっていくあの .pyc ファイルの正体がこれだ。
# バイトコードを確認してみる
python -m dis -d your_script.py
# 実際にバイトコードを覗いてみよう
import dis
def greet(name):
return f"Hello, {name}!"
dis.dis(greet)
実行すると、こんな出力が得られる:
2 0 RESUME 0
3 2 LOAD_CONST 1 ('Hello, ')
4 LOAD_FAST 0 (name)
6 FORMAT_VALUE 0
8 LOAD_CONST 2 ('!')
10 BUILD_STRING 3
12 RETURN_VALUE
この「LOAD_CONST」「LOAD_FAST」が、司書の具体的な作業手順書だ。人間が読めるPythonコードは、最終的にこの機械向けの命令列に変換されて動いている。
この「ソースコードがバイトコードに変換され、仮想マシンで実行される」構造を理解していると、次のセクションで説明するPythonの速度問題がストンと腹落ちするはずだ。
2. なぜPythonは「遅い」のに「最強」なのか
2.1 遅さの正体 — 3つの構造的要因
Pythonが遅いと言われる理由は明確に3つある。
要因1: インタプリタ実行のオーバーヘッド
C言語やRustは、ソースコードを直接マシンコード(CPUが理解する命令)にコンパイルする。一方、CPythonはバイトコードという「中間言語」を経由し、それをPVMが1命令ずつ解釈する。司書が毎回要約メモを読み上げて作業するようなもので、直接本棚に走る(マシンコード実行)よりどうしても遅い。
要因2: 動的型付けのコスト
Pythonでは変数に型がない。x = 42 と書いた x は次の行で x = "hello" になれる。これは司書が本のジャンルラベルを見ずに、毎回中身を開いて確認するような作業だ。C言語なら「この棚は数学の本だけ」と決まっているので確認不要だが、Pythonの司書は毎回「これは数値か?文字列か?リストか?」を調べる。
要因3: GIL(Global Interpreter Lock)
GILはCPython最大の特徴であり制約だ。図書館の比喩で言えば、受付カウンターが1つしかない。
マルチコアCPUを搭載していても、CPythonは一度に1つのスレッドしかPythonバイトコードを実行できない。8コアのCPUを持っていても、Pythonの計算処理では実質1コアしか使えないのだ。
Python 3.13で実験的に「free-threaded mode」(GILなしモード)が導入されました。python --disable-gil で起動できますが、2026年4月時点ではまだ実験段階です。
2.2 それでも「最強」である理由 — 遅いのは表面だけ
ここが多くの人が誤解しているポイントだ。Pythonの「遅さ」は、Pythonのコードが遅いのであって、Pythonから呼び出されるライブラリが遅いわけではない。
クリックでソースコードを展開
```mermaid flowchart LR subgraph python_layer["Python層 - 遅い"] A["import numpy as np\na = np.array(...)"] end subgraph c_layer["C/C++/Fortran層 - 爆速"] B["BLAS/LAPACK\n行列演算"] C["CUDAカーネル\nGPU計算"] end python_layer -->|"呼び出し"| c_layer ```NumPyの行列演算、PyTorchのテンソル計算、scikit-learnの機械学習。これらは内部でC、C++、Fortran、CUDAで書かれた超高速コードを呼び出している。
図書館の比喩に戻ろう。司書(CPython)自身の動きは確かにゆっくりだ。しかし司書は、図書館の奥にある超高速の自動検索システム(C拡張ライブラリ)にリクエストを投げることができる。司書の仕事は「何を検索するか」を指示することであり、検索そのものは機械が高速に実行する。
Pythonが最強なのは、この遅い接着剤としての役割を完璧にこなしているからだ。書きやすさと読みやすさで開発者の生産性を最大化し、性能が必要な部分はC/C++/CUDAに委譲する。この設計思想がPythonの覇権の本質だ。
この「接着剤としてのPython」を支えているのが、次のセクションで解説する型システムとメモリ管理の仕組みだ。
3. 型システム — 動的型付けの光と代償
3.1 「すべてはオブジェクト」
Pythonでは、整数も文字列も関数もクラスも、すべてがオブジェクトだ。
# 整数もオブジェクト
x = 42
print(type(x)) # <class 'int'>
print(id(x)) # メモリアドレスが返る
print(x.__add__(10)) # 52 — 整数にもメソッドがある
# 関数もオブジェクト
def greet():
return "Hello"
print(type(greet)) # <class 'function'>
greet.custom = "属性も追加できる" # 関数に属性を生やせる...!
図書館に並んでいる本(オブジェクト)は、数学書も小説も図鑑も、すべて同じ「本」という形式で管理されている。ジャンル(型)は本の中身を見ないとわからない。これがダックタイピングの考え方だ。
"If it walks like a duck and quacks like a duck, then it must be a duck."
(アヒルのように歩き、アヒルのように鳴くなら、それはアヒルだ)
クリックでソースコードを展開
# ダックタイピングの例
class Dog:
def speak(self):
return "ワン!"
class Cat:
def speak(self):
return "ニャー!"
class Robot:
def speak(self):
return "ピポパポ"
# 型を気にしない。speakメソッドがあれば何でもOK
def make_speak(thing):
print(thing.speak())
make_speak(Dog()) # ワン!
make_speak(Cat()) # ニャー!
make_speak(Robot()) # ピポパポ
3.2 型ヒント — 「貼らなくていいラベル」を貼る選択
Python 3.5で型ヒント(Type Hints)が導入された。動的型付けの柔軟さを保ちつつ、開発者が任意で型情報を付加できる仕組みだ。
クリックでソースコードを展開
```python # 型ヒントなし — 動くが、読む側は引数の型がわからない def calculate_bmi(weight, height): return weight / (height ** 2)型ヒントあり — 意図が明確になる
def calculate_bmi(weight: float, height: float) -> float:
return weight / (height ** 2)
</details>
:::note warn
型ヒントはあくまで「ヒント」です。CPythonは型ヒントを実行時に**一切チェックしません**。型チェックを行うには `mypy` や `pyright` などの静的解析ツールが必要です。
:::
図書館の比喩で言えば、型ヒントは**本にジャンルラベルを貼る行為**だ。ラベルを貼らなくても図書館は運営できるが、貼っておけば司書も利用者も探しやすくなる。ただし、ラベルが間違っていても司書はいちいち確認しない(実行時チェックなし)。
<details>
<summary>クリックでソースコードを展開</summary>
```python
# mypyで静的型チェックを実行する
# pip install mypy
# mypy your_script.py
from typing import Optional
def find_book(title: str, author: Optional[str] = None) -> dict[str, str]:
"""図書館で本を検索する"""
result = {"title": title, "status": "found"}
if author:
result["author"] = author
return result
型システムの理解が深まったところで、次はPythonがメモリをどう管理しているかを見ていこう。「なぜPythonはメモリリークしにくいのか」の答えがここにある。
4. メモリ管理 — 誰も借りていない本は書庫に戻す
4.1 参照カウント方式
CPythonのメモリ管理の基本は参照カウントだ。すべてのオブジェクトが「自分を参照している変数がいくつあるか」を記録している。
図書館で言えば、各本に貸出カードがついている。誰かが借りるとカウントが増え、返却するとカウントが減る。カウントがゼロになった本は、もう誰も必要としていないので書庫に戻される(メモリ解放)。
クリックでソースコードを展開
import sys
a = [1, 2, 3] # リストオブジェクト生成。参照カウント = 1
print(sys.getrefcount(a)) # 2(aからの参照 + getrefcountの引数としての参照)
b = a # 参照カウント = 2(a と b が参照)
print(sys.getrefcount(a)) # 3
del b # 参照カウント = 1(b を削除)
print(sys.getrefcount(a)) # 2
del a # 参照カウント = 0 → メモリ解放!
4.2 循環参照とガベージコレクタ
参照カウント方式には弱点がある。循環参照だ。
クリックでソースコードを展開
# 循環参照の例
a = []
b = []
a.append(b) # a → b
b.append(a) # b → a
del a
del b
# a と b を削除しても、相互に参照し合っているため参照カウントが0にならない
# → 参照カウント方式だけではメモリ解放できない!
これは図書館の本Aが「参考文献: 本B」と書いてあり、本Bが「参考文献: 本A」と書いてある状態だ。貸出カードのカウントだけ見ると「まだ参照されている」ので書庫に戻せない。
この問題を解決するのが、CPythonのガベージコレクタだ。定期的に図書館を巡回して「相互参照しか残っていない本のグループ」を検出し、まとめて書庫に戻す。
import gc
# GCの統計を確認
print(gc.get_stats())
# 手動でGCを実行
collected = gc.collect()
print(f"回収されたオブジェクト数: {collected}")
通常の開発でGCを意識する必要はほとんどありません。ただし、大量のオブジェクトを生成する科学計算やML処理では、gc.disable() で一時的にGCを停止して性能を改善するテクニックがあります。
メモリ管理の仕組みがわかったところで、次はPython開発者が日常的に使う「環境管理」の全体像を整理しよう。pip、venv、conda の「なぜ」を理解すれば、環境トラブルの大半は未然に防げる。
5. エコシステム — pip / venv / conda の「なぜ」
5.1 PyPI — 40万冊の巨大書庫
PyPI(Python Package Index)は、Pythonパッケージの公式リポジトリだ。2026年4月時点で約55万以上のプロジェクトが登録されている。
図書館の比喩で言えば、PyPIは世界中の出版社から本が集まる巨大書庫だ。pip install は、この書庫から本を取り寄せる注文書にあたる。
クリックでソースコードを展開
# パッケージのインストール
pip install numpy
# バージョン指定
pip install numpy==1.26.4
# 依存関係を一括インストール
pip install -r requirements.txt
# インストール済みパッケージの一覧
pip list
# パッケージの詳細情報
pip show numpy
5.2 venv — なぜ仮想環境が必要なのか
Pythonの初心者が最初に躓くポイントの上位に「仮想環境」がある。なぜこんなものが必要なのか。
図書館で考えてみよう。プロジェクトAでは「NumPy 1.24」が、プロジェクトBでは「NumPy 2.0」が必要だとする。図書館に1冊しか置けないなら、AとBを同時に進めることはできない。
venv(仮想環境)は個室の閲覧スペースだ。各個室に必要な本だけを持ち込み、他の個室と干渉しないようにする仕組みだ。
クリックでソースコードを展開
# 仮想環境の作成
python -m venv .venv
# 有効化(Windows)
.venv\Scripts\activate
# 有効化(macOS/Linux)
source .venv/bin/activate
# 仮想環境内でパッケージをインストール
pip install numpy pandas
# 依存関係を記録
pip freeze > requirements.txt
# 無効化
deactivate
5.3 pip / venv / conda / poetry の使い分け
環境管理ツールが乱立しているのもPythonの特徴だ。それぞれの立ち位置を整理する。
| ツール | パッケージ管理 | 環境管理 | 主な用途 |
|---|---|---|---|
| pip + venv | pip | venv | 標準ライブラリ。最もシンプル |
| conda | conda | conda | データサイエンス/ML。非Pythonパッケージも管理可能 |
| Poetry | poetry | poetry内蔵 | アプリケーション開発。依存関係のロックが厳密 |
| uv | uv | uv内蔵 | Rust製の超高速ツール。pip互換で10〜100倍速い |
| Rye | rye | rye内蔵 | Pythonバージョン管理も統合。uv内蔵 |
2025年以降、uv の採用が急速に広がっています。pip互換のコマンド体系で移行コストが低く、速度は圧倒的です。新規プロジェクトでは検討の価値があります。
環境設定ファイル例(3環境: 開発 / 本番 / テスト):
# pyproject.toml(Poetry / uv共通)
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
[project.dependencies]
numpy = ">=1.26"
pandas = ">=2.0"
[project.optional-dependencies]
dev = [
"pytest>=8.0",
"mypy>=1.8",
"ruff>=0.3",
]
test = [
"pytest>=8.0",
"pytest-cov>=4.0",
"hypothesis>=6.0",
]
# 開発環境のセットアップ(uv使用)
uv sync --extra dev
# テスト環境のセットアップ
uv sync --extra test
# 本番環境(最小構成)
uv sync
# .env.development
PYTHON_ENV=development
DEBUG=true
LOG_LEVEL=DEBUG
# .env.production
PYTHON_ENV=production
DEBUG=false
LOG_LEVEL=WARNING
# .env.test
PYTHON_ENV=test
DEBUG=true
LOG_LEVEL=INFO
TEST_DB=sqlite:///test.db
環境管理の全体像が見えたところで、いよいよ核心に迫ろう。「なぜAI/MLはPython一択なのか」、その技術的な背景を解き明かす。
6. なぜAI/MLはPython一択なのか
6.1 歴史的経緯 — NumPyが築いた帝国
AI/MLでPythonが覇権を握ったのは「たまたま」ではない。NumPyの存在が決定的だった。
2005年、Travis Oliphantが既存の数値計算ライブラリを統合してNumPyを作った。NumPyは内部がC言語とFortranで書かれた高速な多次元配列ライブラリであり、Pythonから呼び出せるAPIを提供した。
図書館の比喩で言えば、NumPyは超高速の自動検索・計算システムを図書館に導入した最初の技術者だ。このシステムの上に、SciPy、pandas、scikit-learn、そしてPyTorch、TensorFlowが積み上がった。
6.2 C拡張 — Pythonの「裏口」
PythonにはC拡張APIが用意されている。C/C++で書いた高速なコードを、Pythonからシームレスに呼び出せる仕組みだ。
# Python側から見ると、ただのPython関数に見える
import numpy as np
a = np.random.rand(1000000) # 100万要素の配列
b = np.random.rand(1000000)
# この1行の裏で、C言語の超高速な行列演算が走っている
c = np.dot(a, b)
この「Pythonで書く → 遅い部分だけCで書き直す → Pythonから呼ぶ」というワークフローが、AI/ML分野のデファクトスタンダードになった。
さらにCUDAの登場で、GPUを使った並列計算もPythonから呼び出せるようになった。PyTorchの .to("cuda") 一行でテンソルがGPUに転送されるのは、この仕組みのおかげだ。
クリックでソースコードを展開
import torch
# CPU上のテンソル
x = torch.randn(1000, 1000)
# GPU上に転送(CUDAカーネルが裏で起動)
if torch.cuda.is_available():
x_gpu = x.to("cuda")
# GPU上での行列積 — CUDA C++が実行される
result = torch.mm(x_gpu, x_gpu)
6.3 2026年現在のAI/MLスタック
# 現代的なAI/MLの最小構成例
# requirements.txt
# 数値計算基盤
numpy>=1.26
pandas>=2.0
# 深層学習フレームワーク(どちらか)
torch>=2.3 # PyTorch — 研究/プロトタイプ向き
# tensorflow>=2.16 # TensorFlow — プロダクション向き
# LLM関連
transformers>=4.40 # Hugging Face
accelerate>=0.30 # 分散学習/推論
bitsandbytes>=0.43 # 量子化
# ローカルLLM推論
# llama-cpp-python>=0.2 # llama.cpp のPythonバインディング
# データ可視化
matplotlib>=3.8
AI/MLにおけるPythonの役割が明確になったところで、次は実務で頻出するPythonのエラーとその対処法を整理しよう。「見たことある」で終わらせず、「原因と対策」をテーブル形式でまとめた。
7. よくあるエラーと対処法
| # | エラー | 原因 | 対処法 |
|---|---|---|---|
| 1 | ModuleNotFoundError: No module named 'xxx' |
パッケージ未インストール、または仮想環境の外で実行 |
pip install xxx を確認。仮想環境が有効か which python で確認 |
| 2 | IndentationError: unexpected indent |
インデントの混在(タブとスペース)または不正なインデント | エディタの設定でタブをスペース4つに統一。python -tt script.py で混在検出 |
| 3 | UnicodeDecodeError: 'utf-8' codec can't decode |
ファイルのエンコーディングが UTF-8 でない |
open(file, encoding='cp932') 等で明示指定。chardet で自動検出も可 |
| 4 | RecursionError: maximum recursion depth exceeded |
再帰が深すぎる or 無限再帰 |
sys.setrecursionlimit() で上限変更。ただし根本的にはループへの書き換えを検討 |
| 5 | MemoryError |
メモリ不足 | ジェネレータの使用、バッチ処理の導入、64bit Python の確認 |
| 6 | TypeError: 'NoneType' object is not subscriptable |
None に対してインデックスアクセス |
関数の戻り値が None でないか確認。if result is not None: でガード |
| 7 |
pip install で Permission denied
|
システムPythonへのインストール権限なし |
--user フラグ追加、または仮想環境内で実行 |
| 8 |
SyntaxError: invalid syntax (明らかに正しいのに) |
前の行の括弧閉じ忘れ、またはPythonバージョン不一致 | エラー行の1行前を確認。python --version でバージョンチェック |
| 9 | ImportError: attempted relative import with no known parent package |
スクリプトを直接実行時に相対インポートを使用 |
python -m package.module で実行、または絶対インポートに変更 |
| 10 | AttributeError: module 'xxx' has no attribute 'yyy' |
バージョン違いによるAPI変更、または同名ファイルの衝突 | パッケージバージョン確認。カレントディレクトリに numpy.py 等の同名ファイルがないか確認 |
エラー10の「同名ファイルの衝突」は初心者が非常にハマりやすい罠です。numpy.py、random.py、test.py などの名前でスクリプトを作ると、標準ライブラリやサードパーティパッケージと衝突して謎のエラーが発生します。
8. Python環境診断スクリプト
「何かおかしいけど原因がわからない」ときに使える診断スクリプトを用意した。コピペで使える。
クリックでソースコードを展開
#!/usr/bin/env python3
"""
Python環境診断スクリプト v1.0
- Python実装/バージョン/パスの確認
- 仮想環境の状態チェック
- 主要パッケージのインストール状況
- GIL / GCの状態確認
"""
import sys
import os
import platform
import struct
def diagnose():
print("=" * 60)
print(" Python 環境診断レポート")
print("=" * 60)
# 1. 基本情報
print("\n[1] 基本情報")
print(f" 実装: {platform.python_implementation()}")
print(f" バージョン: {platform.python_version()}")
print(f" ビルド: {platform.python_build()[0]}")
print(f" コンパイラ: {platform.python_compiler()}")
print(f" OS: {platform.system()} {platform.release()}")
print(f" アーキテクチャ: {struct.calcsize('P') * 8}bit")
print(f" 実行パス: {sys.executable}")
# 2. 仮想環境チェック
print("\n[2] 仮想環境")
venv = os.environ.get("VIRTUAL_ENV")
conda = os.environ.get("CONDA_DEFAULT_ENV")
if venv:
print(f" 状態: venv有効")
print(f" パス: {venv}")
elif conda:
print(f" 状態: conda有効")
print(f" 環境名: {conda}")
else:
print(" 状態: 仮想環境なし(システムPython)")
print(" ⚠️ 仮想環境の使用を推奨します")
# 3. 主要パッケージ確認
print("\n[3] 主要パッケージ")
packages = [
"numpy", "pandas", "torch", "tensorflow",
"transformers", "flask", "django", "fastapi",
"requests", "pytest", "mypy", "ruff"
]
for pkg in packages:
try:
mod = __import__(pkg)
ver = getattr(mod, "__version__", "不明")
print(f" ✅ {pkg:20s} {ver}")
except ImportError:
print(f" ❌ {pkg:20s} 未インストール")
# 4. GIL状態(Python 3.13+)
print("\n[4] GIL状態")
if sys.version_info >= (3, 13):
try:
gil_enabled = sys._is_gil_enabled()
status = "有効" if gil_enabled else "無効(free-threaded)"
print(f" GIL: {status}")
except AttributeError:
print(" GIL: 確認不可(標準ビルド)")
else:
print(f" GIL: 有効(Python {platform.python_version()} — free-threadedは3.13以降)")
# 5. GC状態
print("\n[5] ガベージコレクタ")
import gc
print(f" 有効: {gc.isenabled()}")
stats = gc.get_stats()
for i, gen in enumerate(stats):
print(f" 世代{i}: 回収={gen['collected']}, 回収不能={gen['uncollectable']}")
# 6. パス情報
print("\n[6] モジュール検索パス(sys.path)")
for i, p in enumerate(sys.path[:8]):
print(f" [{i}] {p}")
if len(sys.path) > 8:
print(f" ... 他{len(sys.path) - 8}件")
print("\n" + "=" * 60)
print(" 診断完了")
print("=" * 60)
if __name__ == "__main__":
diagnose()
9. ユースケース別ガイド — Pythonで「何ができるか」
ユースケース1: データ分析 — 「Excelの限界を超えた瞬間」
CSVファイルの分析、可視化、統計処理。Excel職人を卒業する第一歩。
クリックでソースコードを展開
import pandas as pd
import matplotlib.pyplot as plt
# CSVの読み込み(Excel: Ctrl+O → Python: 1行)
df = pd.read_csv("sales_data.csv")
# 月別売上集計(Excel: ピボットテーブル → Python: 1行)
monthly = df.groupby("month")["revenue"].sum()
# グラフ描画
plt.figure(figsize=(10, 6))
monthly.plot(kind="bar", color="#00A1B3")
plt.title("月別売上推移")
plt.ylabel("売上(万円)")
plt.tight_layout()
plt.savefig("monthly_revenue.png")
print("グラフを保存しました")
ユースケース2: Web API構築 — 「最小構成のバックエンド」
FastAPIを使えば、数十行で本格的なREST APIが構築できる。
クリックでソースコードを展開
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
in_stock: bool = True
items: list[Item] = []
@app.get("/items")
def list_items():
return items
@app.post("/items")
def create_item(item: Item):
items.append(item)
return {"message": f"'{item.name}' を追加しました", "total": len(items)}
# 起動: uvicorn main:app --reload
ユースケース3: ローカルLLM推論 — 「自分のPCでAIを動かす」
llama.cppのPythonバインディングを使えば、ローカル環境でLLMを動かせる。
details
from llama_cpp import Llama
# GGUFモデルの読み込み
llm = Llama(
model_path="./models/gemma-2-9b-it-Q5_K_M.gguf",
n_ctx=4096, # コンテキスト長
n_gpu_layers=-1, # 全レイヤーをGPUに載せる
verbose=False
)
# 推論実行
output = llm(
"Pythonが他の言語より優れている点を3つ挙げてください。",
max_tokens=512,
temperature=0.7
)
print(output["choices"][0]["text"])
10. 学習ロードマップ — 「次に何を学ぶべきか」
| レベル | 目安期間 | 到達状態 |
|---|---|---|
| Lv.1 基礎固め | 1〜2ヶ月 | 基本文法が書ける。簡単なスクリプトが作れる |
| Lv.2 実践 | 2〜4ヶ月 | 仮想環境を使いこなし、テストを書ける。チーム開発に参加できる |
| Lv.3 専門分岐 | 4〜8ヶ月 | 自分の専門分野のライブラリを使いこなせる |
| Lv.4 深掘り | 8ヶ月〜 | パフォーマンス最適化やGPU計算など、高度な領域に踏み込める |
まとめ
この記事では、Pythonの「正体」を図書館の比喩で解き明かしてきた。振り返ろう。
Pythonは言語仕様の名前であり、実際に動いているのはCPythonという名の司書だ。この司書は一人で受付を回している(GIL)ため動きは遅いが、背後にある超高速の自動システム(C拡張、CUDA)に仕事を投げることで圧倒的な性能を実現している。
本のジャンルラベルを貼らない方式(動的型付け)のおかげで柔軟性は抜群。型ヒントという「任意のラベル」も貼れるようになり、大規模開発にも耐えうる言語に成長した。そして40万冊を超える蔵書(PyPIパッケージ)が、データ分析からWeb開発、AI/MLまであらゆる分野をカバーしている。
個人的な所感として、筆者がRTX 5090でローカルLLM環境を構築する際も、結局すべての起点は pip install だった。CUDAの設定で3日溶かしたこともあるが...orz、それでもPythonのエコシステムがなければローカルAI開発など到底不可能だったと断言できる。
「なんとなく書ける」から「ちゃんとわかる」へ。この記事がその第一歩になれば幸いだ。
参考文献
この記事を読んで「ローカルLLMをPythonで動かしてみたい」と思った方は、こちらのシリーズもどうぞ:
筆者のXアカウントはこちら(@geneLab_999)