python programming knowhow 1

View python programming knowhow 1 flipbook.

Pythonプログラミング実務ノウハウ大全:基礎から設 計・運用・性能改善まで 図1:Python による開発、データ処理、AI 、Web 、自動化を俯瞰するイメージ 画像について:背景のコードや画面表示は概念表現であり、特定の実行環境や実在プロジェクトを再現 したものではありません。 Pythonは、読みやすい構文と豊富なライブラリを備え、自動化、Web、データ分析、AIまで幅広く使え る。ただし、書き始めやすさと長期運用のしやすさは同義ではない。実務では、本体の版、仮想環境、依 存関係、型、例外、ログ、テスト、秘密情報、配布まで設計する必要がある。 本稿は2026年8月6日時点の公式情報を確認し、コード例を原則Python 3.11以上として、基礎から運用判断 までを整理する。 1. Pythonとは何か Pythonは、インタープリタでコードを実行し、動的型付けと自動メモリ管理を備える汎用言語である。対 話環境で一行ずつ試しやすく、同じ言語でCLI、バックエンド、バッチ、分析ノートブックを作れる。標 準ライブラリには、ファイル、JSON、日時、HTTP、SQLite、並行処理、テスト、ログなど、業務処理の 土台が揃う。

実務では、ランタイム、仮想環境・依存、アプリケーション、品質検査、運用の五層に分けると問題を切 り分けやすい。「Pythonが動かない」と一括りにせず、版、環境、import、入力のどこで失敗したかを調 べる。 2. バージョン選定:最新版よりサポート状態を見る 2026年8月6日にPython Developer’s Guideの表を確認すると、3.14と3.13は bugfix 、3.15は prerelease 、 3.12と3.11は security である。 bugfix は正式公開後の安定・保守段階、 security は原則としてセキュ リティ修正のみの段階を表す。したがって、現時点の主たる安定系列は3.14であり、3.15は本番標準では なく先行検証対象である。一方、表上は3.13もまだbugfix段階にあるため、既存案件での継続利用は十分現 実的である。[1] 調査サマリーには3.13を「現行安定版」とする記述があったが、同じ公式表には3.14がbugfix、3.15が prereleaseと明記されているため、本稿では公式表の時制を優先した。なお、Developer’s Guideはブランチ の保守状態を示す資料であり、個々のマイクロ版は公式ダウンロードページで別途確認する。 新規案件の選定手順は次の通りである。 1. 利用するフレームワーク、DBドライバ、数値計算ライブラリが対応する版を調べる 2. 本番OSやコンテナ基盤で公式または信頼できるビルドを入手できるか確認する 3. CIで複数版を試し、警告、テスト、性能を比較する 4. requires-python に下限と必要なら上限を記述する 5. チームの標準版を文書とCI設定の両方へ固定する 「3.11+」を互換基準にすると、 ExceptionGroup 、 except* 、 asyncio.TaskGroup などを利用でき る。3.13で実験的free-threadedモードとJITが導入されたが、free-threadedは既定ではなく、JITも既定で無効 かつ当初の性能向上は控えめと公式に説明されている。採用可否は実測と依存拡張の対応で判断し、 「GILがなくなったから既存コードが自動で高速化する」と考えない。[2] 3. インストールと初期確認 Pythonはpython.orgの公式配布、OSのパッケージ管理、開発環境管理ツール、コンテナイメージなどから 導入できる。どの方法でも重要なのは、実行中のバイナリとpipの接続先を確認することだ。 python --version python -c "import sys; print(sys.executable)" python -m pip --version pip 単体より python -m pip を使うと、今選んだインタープリタに属するpipを明示できる。Windowsで は環境により py -3.14 、macOS/Linuxでは python3 となることがあるため、READMEにはチームで採用 した呼び出しを記す。

OS同梱Pythonを管理者権限で上書きすると、OSツールを壊す可能性がある。アプリ用Pythonとシステム用 Pythonを分離し、グローバル領域へ無差別にパッケージを入れない。インストール後は、CPUアーキテク チャ、SSL、文字コードも確認しておく。 python -c "import platform, ssl; print(platform.platform()); print(platform.machine()); p 4. 仮想環境をプロジェクトごとに分ける 仮想環境は、プロジェクトごとのインタープリタ入口と site-packages を分離する。公式チュートリア ルでも venv とpipによる環境・パッケージ管理が説明されている。[3] python -m venv .venv # macOS / Linux source .venv/bin/activate # Windows PowerShell .venv\Scripts\Activate.ps1 python -m pip install --upgrade pip .venv 自体は通常Gitへ入れない。OSやPythonの場所を内包するため、別環境へコピーするより再作成す る方が安全である。再現性は仮想環境のフォルダではなく、 pyproject.toml 、ロック情報、インストー ル手順、Python版で担保する。 有効化は便利だが必須ではない。CIでは .venv/bin/python のように直接呼べる。トラブル時は次を比較 する。 python -c "import sys; print(sys.prefix); print(sys.base_prefix)" python -m pip list python -m pip check sys.prefix != sys.base_prefix なら一般に仮想環境内である。IDEのインタープリタ選択も .venv へ 合わせる。シェルだけ有効化してIDEが別Pythonを使う、またはその逆、という事故が多い。 5. pip・PyPI・依存関係管理 pipはパッケージを取得・導入するフロントエンドで、既定ではPython Package Index(PyPI)から探す。[3] パッケージ名とimport名が異なること、同名に近い偽パッケージが存在し得ることを前提に、READMEや 設定から正確な名前をコピーする。

python -m pip install "httpx>=0.27,<1" python -m pip show httpx python -m pip check アプリケーションでは、直接依存と間接依存を区別する。直接利用するものはプロジェクト設定へ明示 し、解決結果は採用ツールのロック機構で固定する。ライブラリ配布では過度に厳密な固定が利用者の解 決を妨げるため、互換範囲を宣言する。更新は「全部を一度に最新版」ではなく、小さな差分でテストす る。 依存追加時の確認項目は、配布元、ライセンス、保守状況、対応Python版、ネイティブ拡張の有無、脆弱 性、サイズ、推移的依存、アンインストール可能性である。名前だけを信用せず、公式プロジェクトへの リンクとハッシュ検証を組織方針に応じて行う。 6. pyproject.toml をプロジェクトの中心にする pyproject.toml はTOML形式で、標準化された [build-system] 、 [project] 、 [tool] の各テーブ ルを扱う。 [project] は名前、版、依存、対応Pythonなどのコアメタデータを表す。[4] [build-system] requires = ["setuptools>=77"] build-backend = "setuptools.build_meta" [project] name = "acme-report" version = "0.1.0" description = "社内レポート生成ツール" readme = "README.md" requires-python = ">=3.11" dependencies = [ "httpx>=0.27,<1", ] [project.optional-dependencies] dev = [ "pytest>=8,<9", ] [project.scripts] acme-report = "acme_report.cli:main" ビルドバックエンドはsetuptools、Hatchlingなどから要件に合うものを一つ選ぶ。 [tool.*] にはテストや formatter等の設定を集約できるが、巨大な設定を無理に一ファイルへ詰めない。 setup.py を実行する古 い手順へ戻るのではなく、標準ビルドフロントエンドからwheelとsdistを生成する。

7. 基本構文と読みやすさ Pythonはインデントをブロック構造として扱う。一般にはスペース4個を使い、タブとの混在を避ける。変 数はオブジェクトへの名前付けであり、代入がコピーを意味するとは限らない。 price = 1_200 quantity = 3 total = price * quantity message = f"合計は{total:,}円です" print(message) 比較は連鎖できる。 None は == ではなく is で比較する。真偽値文脈は簡潔だが、 0 や空文字が意味の ある入力なら「未指定」と混同しない。 def normalize_limit(limit: int | None) -> int: if limit is None: return 100 if not 1 <= limit <= 1_000: raise ValueError("limitは1〜1000で指定してください") return limit モジュールはimport時にネットワーク接続や大規模処理を始めない。実行入口は関数にし、直接実行時だ け呼ぶ。 def main() -> int: print("処理を開始します") return 0 if __name__ == "__main__": raise SystemExit(main()) 8. 主要データ型 数値・真偽値・文字列 int は整数、 float は浮動小数点、 bool は真偽値、 str はUnicode文字列である。金額に二進浮動小数 点をそのまま使うと丸め誤差が問題になるため、要件に応じ decimal.Decimal や最小通貨単位の整数を 使う。 list・tuple・dict・set list :順序を持つ可変コレクション tuple :順序を持つ不変コレクション

dict :キーと値の対応 set :重複のない集合、反復的な所属判定 users = ["alice", "bob"] point = (35.0, 139.0) scores = {"alice": 92, "bob": 81} allowed_roles = {"admin", "editor"} if "admin" in allowed_roles: print(scores.get("alice", 0)) 浅いコピーはネストした可変要素を共有する。入力を変更する関数か、新しい値を返す関数かをAPIとし て決め、両方を曖昧に行わない。大量データを一度にlistへ積む必要がなければ、ジェネレータで逐次処理 する。 def positive_numbers(values: list[int]): for value in values: if value > 0: yield value 9. 制御構文:分岐と反復を浅く保つ if 、 elif 、 else で分岐し、 for はイテラブルを巡回する。異常条件を早期return・raiseし、正常経路 のネストを浅くする。 def shipping_fee(total: int, member: bool) -> int: if total < 0: raise ValueError("totalは0以上である必要があります") if member or total >= 5_000: return 0 return 600 enumerate() は番号付き反復、 zip() は複数列の対応、 any() と all() は条件集約に使う。 break 、 continue は処理を明確にする範囲で使う。Python 3.10以降の match は、構造化された複数形の分岐に有 用だが、単純な真偽条件を無理に置き換えない。

def describe(event: dict[str, object]) -> str: match event: case {"type": "created", "id": int(item_id)}: return f"作成: {item_id}" case {"type": "deleted", "id": int(item_id)}: return f"削除: {item_id}" case _: return "不明なイベント" 10. 関数設計と可変デフォルト引数 関数は一つの責務を持ち、入力、出力、副作用、失敗条件を名前と型で示す。位置引数が増えると誤用し やすいため、設定項目はキーワード専用にする。 from collections.abc import Iterable def calculate_total( prices: Iterable[int], *, tax_rate: float = 0.10, ) -> int: if tax_rate < 0: raise ValueError("tax_rateは0以上である必要があります") subtotal = sum(prices) return round(subtotal * (1 + tax_rate)) リストや辞書をデフォルト値へ直接置くと、関数定義時に一度だけ作られ、呼び出し間で共有される。公 式チュートリアルもこの挙動を警告している。[5] def add_tag(tag: str, tags: list[str] | None = None) -> list[str]: result = [] if tags is None else list(tags) result.append(tag) return result None 自体が有効な値なら、専用sentinelを使う。docstringには型注釈の繰り返しではなく、目的、単位、 例外、重要な副作用を書く。 11. クラスと dataclass クラスは、状態とそれを守る操作が一体の場合に使う。単なるデータ容器なら dataclass で定型コード を減らせる。

from dataclasses import dataclass, field from datetime import datetime @dataclass(frozen=True, slots=True) class Order: order_id: str created_at: datetime item_ids: tuple[str, ...] = field(default_factory=tuple) def __post_init__(self) -> None: if not self.order_id: raise ValueError("order_idは空にできません") 可変フィールドには default_factory を使う。 frozen=True は通常の属性再代入を防ぎ、値オブジェク トの意図を表す。ただし内部要素まで自動で不変になるわけではない。 slots=True は属性集合を固定 し、インスタンス辞書を持たない構成にできるが、継承、弱参照、動的属性を必要とする設計では互換性 を確認する。 すべてをクラスにする必要はない。状態を持たない変換は関数、複数実装を差し替える境界は Protocol 、有限の選択肢は Enum や Literal を検討する。巨大な「Manager」クラスへDB、HTTP、計 算、表示を集めない。 12. 例外処理:失敗を分類して因果を残す 例外は「想定外を隠す」仕組みではなく、呼び出し側が処理できる失敗を伝える仕組みである。 except: や except BaseException: は、 KeyboardInterrupt や終了要求まで捕捉するため避ける。捕 捉する範囲を狭くし、具体的な例外を扱う。

import json from pathlib import Path class ConfigError(RuntimeError): pass def load_config(path: Path) -> dict[str, object]: try: with path.open("r", encoding="utf-8") as stream: data = json.load(stream) except FileNotFoundError as exc: raise ConfigError(f"設定ファイルがありません: {path}") from exc except json.JSONDecodeError as exc: raise ConfigError(f"JSONが不正です: {path}:{exc.lineno}") from exc if not isinstance(data, dict): raise ConfigError("設定の最上位はオブジェクトである必要があります") return data raise ... from exc で原因連鎖を残す。ログを出して同じ例外を上位でも再度ログにすると二重記録に なるため、どの境界で記録するか決める。 assert は最適化時に無効化され得るので、外部入力の検証に は使わない。 Python 3.11では複数の例外をまとめる ExceptionGroup と except* 、例外へ文脈を追加する add_note() が導入された。並行タスクなど複数失敗を扱う場合に有用だが、通常の単一例外を無理にグループ化しな い。[6] 13. 型ヒントは実行時検証ではない 型ヒントは、人間、IDE、静的型検査器へ意図を伝える。Python 3.11基準なら list[str] 、 str | None のような現代的構文を使える。 from collections.abc import Mapping, Sequence from typing import NewType, TypedDict UserId = NewType("UserId", str) class UserRow(TypedDict): id: str roles: list[str] def active_ids(rows: Sequence[UserRow]) -> list[UserId]: return [UserId(row["id"]) for row in rows if row["roles"]]

読み取りだけなら引数を list に限定せず Sequence や Iterable にする。ただし、反復を二回行うなら 一回限りのイテレータを受けられる型にしない。 Any は型検査を止めるため、外部JSONなど境界では object として受け、検証後に具体型へ狭める。 型注釈だけでHTTP入力やJSONが安全になるわけではない。外部境界では実行時検証が必要である。型エ ラーを大量の # type: ignore で隠さず、モデルや戻り値の実態を直す。Python 3.12の新しい型パラメー タ構文を使う場合は、 requires-python と利用者環境を3.12以上へ揃える。[7] 14. 標準ライブラリを先に知る サードパーティ依存を増やす前に、標準ライブラリで要件を満たせるか確認する。 pathlib :パス操作 collections 、 itertools 、 functools :コレクションと反復 decimal 、 statistics :数値処理 csv 、 json 、 tomllib :データ形式 datetime 、 zoneinfo :日時・タイムゾーン sqlite3 :組み込みDB argparse :CLI引数 subprocess :外部プロセス concurrent.futures 、 asyncio :並行処理 logging :構造化可能な運用ログ unittest 、 doctest :テスト hashlib 、 hmac 、 secrets :ハッシュ、認証コード、安全な乱数 標準だから常に最適とは限らないが、配布、更新、互換性の負担を減らせる。要件が高度になった時点で 外部ライブラリへ移る。 15. ファイル・JSON・日時処理 ファイル パス連結は文字列ではなく pathlib.Path を使い、ファイルは with で確実に閉じる。テキストのエンコ ーディングを明示する。 from pathlib import Path def read_lines(path: Path) -> list[str]: with path.open("r", encoding="utf-8") as stream: return [line.rstrip("\n") for line in stream]

大容量ファイルでは read() で全件を載せず、一行ずつ処理する。上書きでは一時ファイルへ書いてから 置換するなど、途中失敗で元データを壊さない設計を検討する。ユーザー入力から作るパスは、許可ディ レクトリ外へ出ないか確認する。 JSON JSONのオブジェクトは通常 dict になるが、キーや値の型は信頼できない。パース後に必須項目を検証す る。 default=str で未知型を無差別に文字列化するとデータ品質問題を隠すため、明示的な変換関数を 用意する。 import json from pathlib import Path def save_json(path: Path, data: dict[str, object]) -> None: text = json.dumps(data, ensure_ascii=False, indent=2) path.write_text(text + "\n", encoding="utf-8") 日時 保存・通信する時刻はtimezone-awareにし、UTCを基準に、表示時に地域へ変換する。 from datetime import UTC, datetime from zoneinfo import ZoneInfo now_utc = datetime.now(UTC) tokyo = now_utc.astimezone(ZoneInfo("Asia/Tokyo")) print(tokyo.isoformat()) datetime.utcnow() と utcfromtimestamp() はPython 3.12から非推奨であり、UTC付きの datetime.now(UTC) や datetime.fromtimestamp(value, UTC) を使う。[8] 夏時間、曖昧時刻、業務日 境界がある処理では、単なるUTCオフセットではなくIANAタイムゾーンを使う。 16. asyncio :I/O待ちを構造化する asyncio は、多数のネットワークI/Oなど待ち時間の多い処理を一つのスレッドで効率よく進めるのに向 く。CPU計算を async にしただけでは速くならない。同期ライブラリをイベントループ内で呼ぶと全タス クを止めるため、非同期対応APIまたは適切なスレッド委譲を使う。 Python 3.11の TaskGroup は、グループ内タスクを終了時まで待ち、一部失敗時のキャンセルと例外集約を 構造化する。新規コードでは create_task() と gather() の直接利用より推奨されている。[9]

import asyncio async def fetch_one(item_id: int) -> str: await asyncio.sleep(0.05) return f"item-{item_id}" async def fetch_all(ids: list[int]) -> list[str]: tasks: list[asyncio.Task[str]] = [] async with asyncio.TaskGroup() as group: for item_id in ids: tasks.append(group.create_task(fetch_one(item_id))) return [task.result() for task in tasks] if __name__ == "__main__": print(asyncio.run(fetch_all([1, 2, 3]))) タイムアウトは asyncio.timeout() で境界を作る。キャンセルは正常な制御信号でもあるため、 CancelledError を握りつぶさない。後処理が必要なら finally で行い、捕捉した場合は原則再送出す る。 async def worker() -> None: resource = "open" try: await asyncio.sleep(3600) except asyncio.CancelledError: print("キャンセルを受け、終了処理へ移ります") raise finally: resource = "closed" print(resource) 同時接続数、再試行、タイムアウトを無制限にしない。セマフォや接続プールで上限を設定し、相手サー ビスへの負荷と自システムのメモリを守る。 17. テスト戦略 テストは実装の後付け確認ではなく、変更可能性を作る設計資産である。層を分ける。 単体テスト:純粋な計算、分岐、検証 統合テスト:DB、ファイル、HTTPクライアントとの接続 契約テスト:外部APIやメッセージ形式 E2Eテスト:利用者の主要フロー

# src/acme/calc.py def discount(price: int, rate: float) -> int: if price < 0: raise ValueError("priceは0以上である必要があります") return round(price * (1 - rate)) # tests/test_calc.py import pytest from acme.calc import discount def test_discount() -> None: assert discount(1_000, 0.2) == 800 def test_negative_price() -> None: with pytest.raises(ValueError, match="0以上"): discount(-1, 0.2) テストは成功例だけでなく、境界値、不正入力、タイムアウト、部分失敗、文字コード、タイムゾーンを 含める。時刻、乱数、外部通信を直接埋め込まず、注入可能な境界へ分ける。モックを増やしすぎると実 装詳細のテストになるため、純粋関数化や一時ディレクトリ、ローカルテストサーバーも使う。 CIでは、テスト、型検査、lint、ビルドを同じPython版・依存解決で実行する。失敗したテストを無条件に 再試行して緑にせず、不安定性を記録して修正する。 18. デバッグとロギング デバッグの基本は、再現条件、入力、実行版、直前変更、スタックトレースを保存することだ。 print() は局所確認には有用だが、本番運用では時刻、重大度、ロガー名、相関IDを持つ logging へ寄 せる。 import logging logger = logging.getLogger(__name__) def process(job_id: str) -> None: logger.info("job started", extra={"job_id": job_id}) try: if not job_id: raise ValueError("job_id is empty") except ValueError: logger.exception("job failed", extra={"job_id": job_id}) raise ライブラリ側でルートロガーへ勝手にハンドラを追加せず、アプリ入口で設定する。ログへパスワード、 トークン、Cookie、個人情報、入力全文を出さない。正常な業務エラーをすべてスタックトレース付き

ERRORにすると監視がノイズになるため、利用者起因、再試行可能、障害のレベルを定義する。 breakpoint() 、IDEデバッガ、 pdb で停止し、変数とコールスタックを確認する。再現しない問題で は、診断ログを増やす前に、何を知りたいかを決める。ログ量を増やすこと自体が解決ではない。 19. セキュリティ 秘密情報を直書きしない APIキー、DBパスワード、署名鍵をソース、Git、ノートブック、コマンド履歴へ書かない。ローカルは OSの資格情報管理や適切に除外した環境設定、本番はクラウドやCIのシークレット管理を使う。環境変数 もプロセスや診断画面から見える可能性があるため、権限とログマスキングを設計する。 import os api_token = os.environ.get("ACME_API_TOKEN") if not api_token: raise RuntimeError("ACME_API_TOKENが設定されていません") 入力と実行を分離する 外部入力を eval() や exec() へ渡さない。シェルコマンドは文字列連結せず、 subprocess.run([...], shell=False, check=True) のように引数列で渡す。SQLはプレースホルダを使う。ファイルアップロー ドは名前、サイズ、内容、保存先を検証する。 安全な乱数 認証トークンやパスワードリセット値には random ではなく secrets を使う。公式資料は、 secrets を パスワードや認証トークンなどに適した暗号学的に強い乱数用と説明している。[10] import secrets token = secrets.token_urlsafe(32) 依存パッケージとPython自体のサポート状態を監視し、脆弱性更新を小さく継続する。デシリアライズ、 テンプレート、正規表現、XML、アーカイブ展開など、入力によってCPU・メモリ・パスが操作される箇 所には上限を設ける。 20. 性能改善:推測より計測 Pythonの性能問題は、CPU、I/O、メモリ、外部サービス、アルゴリズムのどこにあるかで対策が変わる。 最初に再現可能な入力と基準値を作り、 cProfile 、 timeit 、メモリ計測、APM等でボトルネックを特 定する。

python -m cProfile -o profile.dat -m acme_report python -m pstats profile.dat 改善の順序は概ね次の通りである。 1. 不要なDB・HTTP・ファイルI/Oを減らす 2. 二重ループを辞書索引や集合判定へ変える 3. 全件読み込みをストリーミングへ変える 4. 標準の組み込み関数や適切なライブラリを使う 5. 純粋で高コストな計算を functools.cache 等でキャッシュする 6. CPU処理はプロセス、I/O待ちはasyncやスレッドを検討する 7. それでも必要ならネイティブ実装や別サービスへ境界を切る from collections.abc import Iterable def select_known(ids: Iterable[str], known: set[str]) -> list[str]: return [item_id for item_id in ids if item_id in known] 微小な構文差より、計算量と外部I/Oの回数が効く。キャッシュは無効化、容量、整合性、プロセス間共有 まで設計する。free-threadedビルドやJITは実験条件を固定してベンチマークし、通常版との互換性・単体 性能を比較する。[2] 21. パッケージングと配布 再利用ライブラリやCLIは、 src レイアウトを使うと作業ディレクトリから偶然importできる問題を減ら しやすい。 acme-report/ ├── pyproject.toml ├── README.md ├── src/ │ └── acme_report/ │ ├── __init__.py │ ├── cli.py │ └── report.py └── tests/ └── test_report.py 配布前にクリーンな仮想環境でビルドし、生成したwheelを別環境へインストールしてCLIとimportを試 す。公開PyPIへ出す必要がなければ、社内レジストリや成果物ストレージを使う。パッケージ名、import 名、CLI名を意図的に決め、ライセンス、README、対応版、変更履歴、所有者を揃える。

版はAPI互換性とリリース方針に沿って付ける。手元のソースツリーだけでテストを通し、wheelに必要フ ァイルが入っていない事故を防ぐため、インストール済み成果物の試験をCIへ入れる。秘密ファイル、テ スト用認証情報、大容量データをsdistへ混入させない。 22. 主な用途と向き不向き Web・API Pythonは、ルーティング、認証、DB、非同期I/Oを備えた各種Webフレームワークを利用できる。向くのは 業務API、管理画面、データ連携、モデル推論APIなどである。高負荷では、アプリだけでなく、リバース プロキシ、プロセス数、DB接続、キャッシュ、キュー、観測性を設計する。 データ分析 表形式処理、統計、可視化、ノートブックの生態系が強い。ただし、ノートブック内の実行順依存、手修 正データ、巨大メモリ消費は再現性を損なう。探索後は処理を関数・モジュールへ移し、入力スキーマ、 乱数seed、データ版、成果物を記録する。 AI・機械学習 学習、評価、推論、データ前処理、実験管理で広く使える。モデル品質だけでなく、データ漏洩、ライセ ンス、プロンプトやモデルの版、GPU環境、再現性、推論コスト、フォールバックを運用対象にする。 Pythonが制御層でも、重い計算はネイティブ実装やアクセラレータで実行されることが多い。 自動化・CLI ファイル変換、API連携、レポート生成、定期バッチに向く。数十行で始められるが、業務へ定着した時 点で入力検証、dry-run、冪等性、終了コード、ログ、再試行、ロックを追加する。一度きりのスクリプト が重要システムへ成長する前提で、所有者を決める。 用途選択では、性能、配布先、制約、チーム経験を比較する。 23. チーム運用 推奨する最小構成は次の通りである。 pyproject.toml を設定とメタデータの正とする Python版と依存解決結果を固定する src/ と tests/ を分離する formatter、lint、型検査、テストをCIで実行する プルリクエストを小さくし、設計意図と検証結果を書く リリース成果物をクリーン環境で試す ログ、メトリクス、アラート、当番・連絡先を決める

サポート終了と依存更新を定期確認する ローカルとCIで別コマンドを使わず、 make test やタスクランナー等の共通入口を置く。READMEには 最初のセットアップ、実行、テスト、よくある失敗、リリース方法を書く。詳細な規約を文章だけにせ ず、可能なものは自動検査へ移す。 コードレビューでは、スタイルより先に、入力境界、例外、データ損失、並行性、セキュリティ、テスト 可能性を見る。型ヒントやformatterを導入しても、責務分離と命名の判断は自動化できない。退職者の個 人アカウント、個人PC、個人PyPIトークンに依存しない。 24. Pythonのメリット 読み書きしやすく試行が速い 構文のノイズが比較的少なく、REPLで小さく確認できる。業務担当者と開発者が処理を一緒に読める場 合も多く、試作から改善までの距離が短い。 生態系と標準ライブラリが広い Web、分析、AI、自動化、テストなど、多くの領域で既存資産を利用できる。同じ言語でデータ準備、 API、運用スクリプトをつなげられる。 段階的に品質を上げられる 短いスクリプトから始め、関数、型、テスト、パッケージ、CIを追加できる。プロトタイプと本番の間を 同一言語で移行しやすい。 複数OSで動かしやすい 純粋Python部分は複数OSへ移しやすい。ただし、パス、改行、プロセス、ネイティブ拡張には差があるた め、CIで対象OSを試す必要がある。 25. Pythonのデメリット 実行速度とメモリ 動的なオブジェクトモデルやインタープリタ実行は、低レベル言語よりCPU・メモリ面で不利になる場合 がある。アルゴリズム改善、ネイティブライブラリ、並列化、別言語境界を使い分ける。 動的型付けによる遅い発見 型や属性の誤りが特定経路を実行するまで見つからないことがある。型ヒント、静的検査、テストで補う が、外部データは実行時検証が必要である。 環境・依存関係が混乱しやすい

Python本体、pip、仮想環境、IDE、ネイティブwheelの組み合わせで「自分のPCだけ動く」が起こる。版 と環境を明示し、クリーンビルドを自動化する。 配布先によって難易度が変わる サーバーでは扱いやすい一方、Python未導入のデスクトップへ単一実行ファイルとして配る、モバイルや ブラウザで直接動かす、といった要件は追加設計が必要になる。 並行処理モデルの選択が必要 スレッド、プロセス、async、free-threadedの特性が異なる。CPU処理へasyncを使う、同期I/Oをイベントル ープで呼ぶなど、誤った選択は複雑性だけを増やす。 26. トラブルシューティング python や pip が見つからない PATH、シェル再起動、インストール場所を確認する。 python -m pip が動くか、 sys.executable が意 図した版かを見る。管理者権限で場当たり的に再インストールしない。 ModuleNotFoundError 仮想環境とIDEのPythonが一致するか、パッケージがその環境へ入ったか、作業ファイル名が json.py や logging.py など標準モジュールと衝突していないか確認する。プロジェクト自身は編集可能インストー ルまたは正しいパッケージ構成で扱う。 pipの依存解決が衝突する エラーに出る要求範囲を読み、直接依存と間接依存を特定する。無理な --force で上書きせず、互換版 へ揃えるか、依存元を更新・交換する。 pip check とクリーン環境で確認する。 文字化け・ UnicodeDecodeError ファイルの実際の文字コードと encoding 指定を確認する。エラーを無条件の errors="ignore"