ロバストPython

―クリーンで保守しやすいコードを書く

[cover photo]
TOPICS
Programming , Python
発行年月日
PRINT LENGTH
384
ISBN
978-4-8144-0017-1
原書
Robust Python
FORMAT
Print PDF EPUB
Ebook
3,960円
Ebookを購入する
Print
3,960円

Pythonはシンプルな構文で読みやすいプログラミング言語ですが、コードをロバストにする機能も備わっています。本書では、Python 3.5から導入された型ヒントを使って、ロバストなPythonコードを記述する方法にアプローチします。全4部構成のうち、Ⅰ部とⅡ部ではPythonにおける型ヒントの位置づけや組み込み型について基本的な事柄をしっかりおさえ、ユーザ定義型を使う方法、部分型、プロトコル、pydanticによる実行時型チェックなど、Pythonの型システムを最大限に活用する方法を詳しく説明します。Ⅲ部は依存関係や設計手法について、Ⅳ部はセーフティネットとして高度なテスト手法を扱います。本書の内容を理解すれば、クリーンで保守しやすいPythonコードが書けるようになります。

正誤表

ここで紹介する正誤表には、書籍発行後に気づいた誤植や更新された情報を掲載しています。以下のリストに記載の年月は、正誤表を作成し、増刷書籍を印刷した月です。お手持ちの書籍では、すでに修正が施されている場合がありますので、書籍最終ページの奥付でお手持ちの書籍の刷版、刷り年月日をご確認の上、ご利用ください。

第1刷正誤表

※2023年6月更新

■P.117 1-3行目
【誤】
    DAIRY = auto()
    SEAFOOD = Allergen.FISH | Allergen.SHELLFISH
    ALL_NUTS = Allergen.TREE_NUTS | Allergen.PEANUTS
【正】
    DAIRY = auto()

SEAFOOD = Allergen.FISH | Allergen.SHELLFISH
ALL_NUTS = Allergen.TREE_NUTS | Allergen.PEANUTS

■P.218 下から9行目
【誤】
    raise NotImplementedError("この内容の通知には通知手段が用意されていません")
【正】
    else:
        raise NotImplementedError("この内容の通知には通知手段が用意されていません")

目次

監訳者まえがき
はじめに

1章 ロバストPython入門
    1.1 ロバストネスとは
        1.1.1 ロバストネスはなぜ大切なのか
    1.2 あなたの意図は何か
        1.2.1 非同期コミュニケーション
    1.3 意図を伝えるための手法
        1.3.1 コレクション
        1.3.2 イテレーション
        1.3.3 驚き最小の原則
    1.4 まとめ

第I部 型アノテーション

2章 Pythonデータ型入門
    2.1 データ型には何が含まれているか
        2.1.1 機械的な表現
        2.1.2 意味論的な表現
    2.2 型システム
        2.2.1 強い型付けと弱い型付け
        2.2.2 動的型付けと静的型付け
        2.2.3 ダックタイピング
    2.3 まとめ

3章 型アノテーション
    3.1 型アノテーションとは何か
    3.2 型アノテーションの利点
        3.2.1 自動補完
        3.2.2 型チェッカ
        3.2.3 演習:バグ探し
    3.3 いつ型アノテーションを使うべきか
    3.4 まとめ

4章 型制約
    4.1 Optional型
    4.2 Union型
        4.2.1 データ型の積と和
    4.3 Literal型
    4.4 Annotated型
    4.5 NewType型
    4.6 Final型
    4.7 まとめ

5章 コレクション型
    5.1 コレクションの型アノテーション
    5.2 同種コレクションと異種コレクション
    5.3 TypedDict
    5.4 新しいコレクション型の作成
        5.4.1 ジェネリクス
        5.4.2 既存のデータ型の変更
        5.4.3 簡単に使えるABC
    5.5 まとめ

6章 型チェッカのカスタマイズ
    6.1 型チェッカの設定
        6.1.1 mypyの設定
        6.1.2 mypyのレポート
        6.1.3 mypyの高速化
    6.2 mypy以外の型チェッカ
        6.2.1 Pyre
        6.2.2 Pyright
    6.3 まとめ

7章 実践的な型チェックの導入
    7.1 トレードオフ
    7.2 早く付加価値を手に入れる方法
        7.2.1 ペインポイントを特定する
        7.2.2 対象コードの戦略的な選択
        7.2.3 ツールの活用
    7.3 まとめ

第II部 ユーザ定義型

8章 列挙型
    8.1 ユーザ定義型
    8.2 列挙型
        8.2.1 Enum
        8.2.2 列挙型を使うべきではない場合
    8.3 高度な使い方
        8.3.1 auto()
        8.3.2 Flag
        8.3.3 整数への変換
        8.3.4 unique
    8.4 まとめ

9章 データクラス
    9.1 データクラスの実際
    9.2 使い方
        9.2.1 文字列への変換
        9.2.2 等価比較
        9.2.3 比較
        9.2.4 イミュータブル
    9.3 他のデータ型との比較
        9.3.1 データクラスと辞書
        9.3.2 データクラスとTypedDict
        9.3.3 データクラスと名前付きタプル
    9.4 まとめ

10章 クラス
    10.1 クラスの解剖
        10.1.1 オブジェクトの初期化
    10.2 不変式
        10.2.1 不変式を維持する方法
        10.2.2 不変式が有益な理由
        10.2.3 不変式の伝え方
        10.2.4 クラスの利用者への伝え方
        10.2.5 メンテナへの伝え方
    10.3 不変式のカプセル化と保守
        10.3.1 カプセル化とは何か
        10.3.2 データアクセス保護
        10.3.3 操作、演算
    10.4 まとめ

11章 インタフェースの定義
    11.1 自然に使えるインタフェースの設計方法
        11.1.1 利用者のように考える
    11.2 自然なインタラクション
        11.2.1 自然なインタフェースの実現
        11.2.2 特殊メソッド
        11.2.3 コンテキストマネージャ
    11.3 まとめ

12章 部分型
    12.1 継承
    12.2 置換可能性
    12.3 設計で考慮すべきこと
        12.3.1 コンポジション
    12.4 まとめ

13章 プロトコル
    13.1 2つの型システムの間の緊張関係
        13.1.1 データ型を指定しないかAnyを使う
        13.1.2 Unionを使う
        13.1.3 継承を使う
    13.2 プロトコル
        13.2.1 プロトコルの定義
    13.3 高度な用法
        13.3.1 複合プロトコル
        13.3.2 実行時チェックできるプロトコル
        13.3.3 プロトコルを満たすモジュール
    13.4 まとめ

14章 pydanticによる実行時型チェック
    14.1 動的な設定
    14.2 pydantic
        14.2.1 バリデータ
        14.2.2 バリデーションとパースの違い
    14.3 まとめ

第III部 大規模な変更への対応

15章 拡張性
    15.1 拡張性とは何か
        15.1.1 設計のやり直し
    15.2 開放閉鎖の原則
        15.2.1 OCP違反の見つけ方
        15.2.2 欠点
    15.3 まとめ

16章 依存関係
    16.1 関係
    16.2 依存関係のタイプ
        16.2.1 物理的依存関係
        16.2.2 論理的依存関係
        16.2.3 時間的依存関係
    16.3 依存関係の可視化
        16.3.1 パッケージの可視化
        16.3.2 インポートの可視化
        16.3.3 関数呼び出しの可視化
    16.4 まとめ

17章 コンポーザビリティ
    17.1 コンポーザビリティとは何か
    17.2 ポリシーとメカニズム
    17.3 小規模な部品のコンポーザビリティ
        17.3.1 コンポーザブルな関数
        17.3.2 コンポーザブルなアルゴリズム
    17.4 まとめ

18章 イベント駆動アーキテクチャ
    18.1 仕組み
        18.1.1 欠点
    18.2 単純イベント
        18.2.1 メッセージブローカーを使う
        18.2.2 Observerパターン
    18.3 ストリーミングイベント
    18.4 まとめ

19章 プラガブルPython
    19.1 Template Methodパターン
    19.2 Strategyパターン
    19.3 プラグインアーキテクチャ
    19.4 まとめ

第IV部 セーフティネットの構築

20章 静的解析
    20.1 リンター
        20.1.1 独自のPylintプラグインの開発
        20.1.2 プラグインの仕組み
    20.2 その他の静的解析ツール
        20.2.1 複雑度チェッカ
        20.2.2 セキュリティ解析
    20.3 まとめ

21章 テスト戦略
    21.1 テスト戦略の立て方
        21.1.1 テストとは何か
    21.2 テストにかかるコストの削減方法
        21.2.1 AAAテスト
    21.3 まとめ

22章 受け入れテスト
    22.1 振る舞い駆動開発
        22.1.1 Gherkin
        22.1.2 実行可能な仕様
    22.2 behaveのその他の機能
        22.2.1 ステップのパラメータ化
        22.2.2 テーブル駆動の要件
        22.2.3 ステップマッチャー
        22.2.4 テストのライフサイクルのカスタマイズ
        22.2.5 タグを使ったテストの選択的な実行
        22.2.6 レポートの生成
    22.3 まとめ

23章 プロパティベーステスト
    23.1 Hypothesisによるプロパティベーステスト
        23.1.1 Hypothesisの魔術
        23.1.2 従来のテストとの違い
    23.2 Hypothesisのフル活用
        23.2.1 Hypothesisストラテジ
        23.2.2 生成アルゴリズム
    23.3 まとめ

24章 ミューテーションテスト
    24.1 ミューテーションテストとは何か
    24.2 mutmutによるミューテーションテスト
        24.2.1 ミュータントテストで見つかったテストの穴の修復
        24.2.2 ミューテーションテストレポート
    24.3 ミューテーションテスト導入の難点
        24.3.1 カバレッジ(およびその他の指標)の嘘
    24.4 まとめ

索引

コラム目次
    クリーンコードの重要性
    自己文書化(self-documenting)コード
    動的インデックスと静的インデックス
    3.5よりも前のPythonで使える型アノテーション
    例外
    型エイリアス
    ジェネリクスのその他の用途
    EnumかLiteralか
    アサーションか例外か
    例外を使いたくない場合はどうするか
    SOLID原則
    不変式チェックをすると遅くなるか
    すべてのプライベートメンバにゲッターやセッターを用意すべきか
    @staticmethodと@classmethodはどうするか
    多重継承
    継承以外の部分型
    プロトコルは継承を不要にするか
    ピン留めすべきかせざるべきか
    DRYしすぎたコード
    現場におけるコンポーザビリティ
    クラスなしのパターン
    原典におけるTemplate Methodパターン
    エラーをシフトレフトせよ
    手動テストについて
    pytestの使い方
    Hypothesisデータベース