Python | OOP:str

Python Python
スポンサーリンク

概要(strは「人に見せる文字列表現」を返す特別メソッド)

strは、オブジェクトをprintしたり、str()に渡したときの“人向けの文字列表現”を定義します。これを実装しておくと、ログやUI、コンソール表示が一気に読みやすくなります。初心者がまず押さえるべきは、strの役割、reprとの違い、フォーマットのコツ、そしてデバッグ・ロギングで迷わない設計です。


基本の使い方(printやstr()で呼ばれる仕組み)

最小例と動作の確認

class Person:
    def __init__(self, name: str, age: int):
        self.name = name
        self.age = age

    def __str__(self) -> str:
        return f"{self.name}{self.age}歳)"

p = Person("太郎", 23)
print(p)          # 太郎(23歳) ← __str__が使われる
print(str(p))     # 同じく__str__が使われる
Python

「人に見せたい形」を素直に作るのが基本です。f文字列を使うと簡潔に書けます。

reprとの違い(役割の線引き)

class Person:
    def __init__(self, name: str, age: int):
        self.name = name; self.age = age

    def __str__(self) -> str:         # 人向け(UI/ログの短い表現)
        return f"{self.name}{self.age}歳)"

    def __repr__(self) -> str:        # 開発者向け(再現可能性を意識)
        return f"Person(name={self.name!r}, age={self.age!r})"
Python

UIやログの一行表示はstr、デバッグやREPLでの詳細はrepr。両方実装しておくと場面で使い分けできます。


設計のコツ(安定した表示・個人情報の扱い・長さ管理)

表示は「短く・安定・情報量は適度に」

ログやUIでは、行が長すぎると読みにくくなります。要点(主要属性)を短くまとめ、可変長データは件数やサマリにします。

class Order:
    def __init__(self, order_id: str, items: list[tuple[str, int]]):
        self.order_id = order_id
        self.items = items

    def __str__(self) -> str:
        count = len(self.items)
        return f"Order#{self.order_id} items={count}"
Python

機微情報はマスクする

APIキーやトークン、メールなどは“そのまま出さない”のが安全設計です。strは人目に触れる機会が多いので、必ずマスクしましょう。

class ApiKey:
    def __init__(self, token: str):
        self.token = token

    def __str__(self) -> str:
        t = self.token
        return t[:4] + "..." + t[-4:] if len(t) > 8 else "***"
Python

エラー時も壊れない表示

欠損値やNoneが来ても例外にせず、デフォルト表現を返すとログ出力中の失敗を防げます。

class User:
    def __init__(self, name: str | None, id_: str | None):
        self.name = name or "unknown"
        self.id_ = id_ or "-"

    def __str__(self) -> str:
        return f"User[{self.id_}] {self.name}"
Python

実務例(Web/APIのモデル・クライアント・例外で活かす)

モデルの見やすい一行サマリ

APIレスポンスを整えたモデルは、strで俯瞰できるようにしておくと、ログ・デバッグ効率が上がります。

class UserModel:
    def __init__(self, data: dict):
        self.user_id = str(data.get("id", ""))
        self.name = data.get("name") or "unknown"
        self.role = data.get("role") or "user"

    def __str__(self) -> str:
        return f"User({self.user_id}, {self.name}, role={self.role})"
Python

クライアントの接続概要を短く

接続先とタイムアウトなど、運用で重要な設定を一目でわかる形にします。

import requests

class ApiClient:
    def __init__(self, base_url: str, api_key: str, timeout: float = 5.0):
        self.base_url = base_url
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({"Authorization": f"Bearer {api_key}"})

    def __str__(self) -> str:
        return f"ApiClient({self.base_url}, timeout={self.timeout})"
Python

例外型の文字列表現で文脈を伝える

ドメイン例外のstrに簡潔な説明と主要IDを含め、ログで原因追跡しやすくします。

class ServiceError(Exception):
    def __init__(self, message: str, uid: str | None = None):
        super().__init__(message)
        self.uid = uid

    def __str__(self) -> str:
        return f"{self.args[0]} (uid={self.uid or '-'})"
Python

深掘り(strを使う場面、フォールバック、テストの観点)

どこで使われるか(暗黙の呼び出し)

  • print(obj)、format文字列(f”{obj}”)、loggingでの%や{}フォーマットなど、表示系で暗黙にstrが呼ばれます。
  • デバッグシェル(REPL)は通常reprを使う点に注意。必要ならreprも実装しましょう。

reprへのフォールバック

strが未実装のとき、str(obj)はreprの結果を使います。最初はreprだけ用意するのも現実的です。両方をセットで整えるのが理想。

テストの書き方(安定性の検証)

  • 期待する文字列を固定化し、主要属性の更新で表示が正しく変わること、欠損時に安全な代替表現になることをアサートします。
  • 機微情報がマスクされていることを必ずテストします。

例題(注文ドメインの表示を整えて運用しやすくする)

注文・ユーザー・クライアントの表示を統一する

class Order:
    def __init__(self, order_id: str, items: list[tuple[str, int]]):
        self.order_id = order_id
        self.items = items
        self.status = "init"

    def __str__(self) -> str:
        return f"Order#{self.order_id} status={self.status} items={len(self.items)}"

class UserModel:
    def __init__(self, uid: str, name: str | None = None):
        self.uid = uid
        self.name = name or "unknown"

    def __str__(self) -> str:
        return f"User({self.uid}, {self.name})"

import requests
class Client:
    def __init__(self, base_url: str, key: str, timeout: float = 5.0):
        self.base_url = base_url
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update({"Authorization": f"Bearer {key}"})

    def __str__(self) -> str:
        return f"Client({self.base_url}, timeout={self.timeout})"
Python

このように、主要なクラスのstrを揃えておくと、ログに出たときに全体像がすぐ掴めます。


まとめ(strは“人に伝わる一行”を作るための出口)

strは、人間に読ませるための文字列表現を返す特別メソッドです。UI・ログ・メッセージでのわかりやすさが大幅に向上します。reprとの役割分担を守り、短く・安定・機微情報はマスクし、欠損でも落ちない表現を心がける。主要クラスに一貫したstrを用意するだけで、デバッグ速度と運用の安心感が段違いになります。

タイトルとURLをコピーしました