Yomiage
メニュー

Python実践講座 17:総合演習・タスクのモデルと入力検証

更新 2026/9/27 6:22:11 公開

投稿者: しゅりりん

ここから第19回で、JSONへ保存できるタスク管理CLIを作ります。前提は第01〜16回です。操作はadd、list、doneです。

型注釈の先にある検証

タスクは正の整数ID、1〜200コードポイントの題名、真偽の完了状態を持ちます。題名の前後の空白を除き、改行とタブは認めません。doneを二度実行しても完了状態を保ち、存在しないIDはエラーとします。同時に複数プロセスが更新する用途は対象外です。

新しいフォルダへdomain.pyを保存します。

from dataclasses import dataclass, replace


@dataclass(frozen=True)
class Task:
    id: int
    title: str
    done: bool = False

    def __post_init__(self):
        if type(self.id) is not int or self.id <= 0:
            raise ValueError("IDは正の整数です")
        if type(self.title) is not str:
            raise ValueError("題名は文字列です")
        title = self.title.strip()
        if not 1 <= len(title) <= 200 or any(c in title for c in "\t\n\r"):
            raise ValueError("題名は改行・タブなしの1〜200文字です")
        if type(self.done) is not bool:
            raise ValueError("完了状態は真偽値です")
        object.__setattr__(self, "title", title)

    def complete(self):
        return replace(self, done=True)

    @classmethod
    def from_dict(cls, data):
        if not isinstance(data, dict) or set(data) != {"id", "title", "done"}:
            raise ValueError("タスクの項目が不正です")
        return cls(data["id"], data["title"], data["done"])

このファイルは次回のCLIからimportします。python -c "from domain import Task; print(Task(1, '復習').complete())" で、完了状態のTaskを確認できます。frozenな値の初期化時だけ、object.__setattr__で正規化した題名を設定しています。

入力の入口を一つにする

JSONから読み込む辞書も、CLIの文字列も、最終的には同じTaskの検査を通します。型注釈は実行時に自動で強制されないため、外部入力に必要な検査を明示しています。boolを整数IDとして通さない点にも注意してください。

保存形式はバージョン番号とtasks配列を持つJSONにします。将来項目が増えた場合、どの形式で保存したデータかを識別できるようにするためです。未知の項目を勝手に捨てて上書きすると、別の版が保存した情報を失うことがあります。この教材では未知の項目を拒否する方針です。

練習と解答

練習:IDがTrue、題名が空白だけ、doneが文字列の「false」の入力を試します。

解答:すべてValueErrorです。bool("false") はTrueになるため、真偽の変換へ安易に使えません。入力仕様に従い、受け入れる表記を列挙して変換するか、この例のようにJSONの本当の真偽値だけを認めます。

公式資料

dataclassesが参照先です。


Python全20回の目次 | 前の回 | 次の回

このブラウザでは Web Speech API が利用できません。

1 / 16 · 停止中