Pokazać dwa sposoby modelowania interfejsów: nominalny (ABC) i strukturalny (Protocol).
Interfejs to zestaw metod, który klasa musi zaimplementować.
W językach takich jak Java interface jest słowem kluczowym.
W Pythonie interfejs można wyrazić na dwa sposoby.
from abc import ABC, abstractmethod
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, amount: float) -> str:
...- Klasa dziedzicząca musi zaimplementować
pay, inaczejTypeErrorprzy próbie instancji. - Sprawdzenie:
isinstance(obj, PaymentProcessor)→True.
class CardProcessor(PaymentProcessor):
def pay(self, amount: float) -> str:
return f"card:{amount:.2f}"from typing import Protocol
class SupportsPay(Protocol):
def pay(self, amount: float) -> str:
...- Klasa nie musi po nim dziedziczyć — wystarczy, że ma metodę
pay. - Sprawdzenie: statycznie przez mypy/pyright, nie przez
isinstance. - Idealne gdy nie kontrolujemy klas zewnętrznych.
| Kryterium | ABC |
Protocol |
|---|---|---|
| Wymagana jawna deklaracja | Tak (class Foo(ABC)) |
Nie |
| Weryfikacja runtime | isinstance |
Brak (tylko statyczna) |
| Sprawdza zewnętrzne klasy | Nie | Tak |
| Wymusza implementację | Tak | Nie (tylko linter) |
Diagram: diagrams/topic_11.png
Plik: examples/interfaces_demo.py
from abc import ABC, abstractmethod
from typing import Protocol
class PaymentProcessor(ABC):
@abstractmethod
def pay(self, amount: float) -> str:
...
class SupportsPay(Protocol):
def pay(self, amount: float) -> str:
...
class CardProcessor(PaymentProcessor):
def pay(self, amount: float) -> str:
return f"card:{amount:.2f}"- Uruchom
examples/interfaces_demo.py. - Utwórz instancję
PaymentProcessor()— co się dzieje? - Napisz
BlikProcessorbez dziedziczenia poPaymentProcessor. - Sprawdź
isinstance(blik, PaymentProcessor)— wynik? - Napisz funkcję z podpowiedzią
SupportsPay— czyBlikProcessorpasuje?
- Student rozróżnia podejście nominalne i strukturalne do interfejsów.
- Student wie, kiedy użyć
ABC, a kiedyProtocol.
- szablon:
exercises/tasks.py - przykładowe rozwiązanie:
exercises/solutions_11.py - testy:
exercises/test_solutions.py
Zadanie: napisz klasę BlikProcessor z metodą pay(amount) -> str w formacie "blik:<kwota:.2f>".
- Czym różni się
ABCodProtocol? - Kiedy warto stosować nominalne interfejsy (
ABC)? - Co daje typowanie strukturalne (
Protocol) w praktyce projektowej? - Jak interfejsy wspierają testowanie (mockowanie)?
- Dlaczego interfejs zmniejsza sprzężenie między modułami?
- https://docs.python.org/3/library/abc.html
- https://docs.python.org/3/library/typing.html#typing.Protocol
- L. Ramalho, Fluent Python, rozdz. „Protocols and Duck Typing".
