We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Interfaces with Protocols and ABCs step 2 of 26
Write a Protocol for Three Unrelated Classes
A storage report adds up the size of every blob, text file and network
packet that a user keeps. The three classes have nothing in common except a
size_bytes() method. Write a protocol for that method, and a function that
totals any mix of the three.
total_size([Blob(1), TextFile("ab"), Packet(2)]) # 1 + 2 + 16 = 19
What to write
SupportsSizeBytes is a Protocol with one method:
def size_bytes(self) -> int: ...
Each class gets its own size_bytes():
| Class | Stored value | size_bytes() returns |
|---|---|---|
Blob |
nbytes: int |
nbytes |
TextFile |
text: str |
the number of bytes in text.encode("utf-8") |
Packet |
words: int |
4 * words + 8, four bytes per word plus an eight-byte header |
Keep Blob a frozen dataclass, TextFile a plain class and Packet a
NamedTuple. None of them inherits from SupportsSizeBytes. mypy matches
each one by its size_bytes method.
total_size(items: Iterable[SupportsSizeBytes]) -> int adds up
size_bytes() over items. Call the method on each item, without checking
which class it is. Accept any iterable, including a generator, which you can
read only once.
solve(blob_sizes, texts, packet_words) makes one Blob per entry in
blob_sizes, one TextFile per entry in texts and one Packet per entry
in packet_words. Put them all in one list, and return total_size(items).
Start the list with this annotation:
items: list[SupportsSizeBytes] = []
The annotation tells mypy what the list holds, so it checks each object you
add against the protocol. Without it, mypy reports
Need type annotation for "items". A list written out as
[Blob(1), TextFile("a")] gets the type list[object], which total_size
rejects.
Edge cases
- Text sizes count bytes, not characters.
"héllo"is 6 bytes, and"日本語"is 9. - A packet with zero words is still 8 bytes.
- An empty text is 0 bytes, and three empty lists total 0.
- Count repeated entries separately, and leave the input lists unchanged.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.