typing.Protocol とインターフェース分離原則

Event:

[特集:型] Python Meetup Fukuoka #7 LT

Presented:

2026/06/05 nikkie

伝えたいこと

  • typing.Protocolインターフェース と捉えられる

  • インターフェースは 使い方を示す もの

  • 色々知らなくても使えるよう「インターフェースは小さく」(インターフェース分離原則。SOLID原則のI)

typing.Protocol

from typing import Protocol


class Proto(Protocol):
    def meth(self) -> int: ...

何のためのもの?ー静的ダックタイピング🐤

  • ダックタイピング 「アヒルのように見えて、アヒルのように鳴けば、それはアヒルである。」

    • 型を見ない。振る舞い優先

  • typing.Protocol型チェッカに伝わるダックタイピング

ABC(抽象基底クラス)とは違う?

ABC:

どのクラスを継承したか(名前)

typing.Protocol:

どのメソッドを持っているか

Structural Subtyping(構造 で型を見る)

例:SupportsClose protocol

close() できるもの [1]
from typing import Protocol


class SupportsClose(Protocol):
    def close(self) -> None: ...

SupportsClose で型ヒント

close_all()close() できるものを受け取る
from collections.abc import Iterable


def close_all(items: Iterable[SupportsClose]) -> None:
    for item in items:
        item.close()

静的ダックタイピング!

close(self) -> None を持つので 型チェッカは受け入れる
class Resource:  # SupportsCloseを継承していない
    def close(self) -> None:
        self.resource.release()


close_all([Resource(), open("some/file")])  # 型チェッカはOK

💡 SupportsClose使い方 を表している

close_all() から見える世界:

  • close() が呼べる(使い方)

  • それ以外は関心がない

ISP:インターフェース分離原則

  • SOLID原則(5つの設計原則)の1つ

  • 私の理解:インターフェースは使い方を過不足無く示す

  • typing.Protocol による protocol はインターフェースと捉えられる!

大きすぎるProtocol

close_all() が使わない other_method()
class BigProtocolExample(Protocol):
    def close(self) -> None: ...
    def other_method(self) -> None: ...


def close_all(items: Iterable[BigProtocolExample]) -> None:
    for item in items:
        item.close()

提案:ISPに沿って、小さく分けましょう

最小の使い方 (protocol)で使う側へ示す
class SupportsClose(Protocol):
    def close(self) -> None: ...


class OtherProtocol(Protocol):
    def other_method(self) -> None: ...

まとめ🌯 typing.Protocol とインターフェース分離原則

  • typing.Protocol はインターフェースとして気づき、ISPを適用した

  • Protocol を小さくして、使い方を表してみては

ご清聴ありがとうございました!

../_images/uzabase-white-logo.png

参考