We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← From Everyday Python to Production Code step 4 of 223
Placement 2/6: Match Objects by the Methods They Have
Solve this without the hints and you can skim the protocols track.
Duck and Robot each have a speak() -> str method. Rock has roll()
instead. They share no base class. You want to ask any of them to speak, if it
can.
A protocol describes that need. It is a class that lists the methods an object must have. Any class with those methods matches it, without inheriting from it. The starter defines one:
class Speaker(Protocol):
def speak(self) -> str: ...
To mypy, an abstract base class, or ABC, matches only its subclasses. Using
one here would mean changing Duck and Robot to inherit from it. A protocol
leaves them alone.
What to write
Add the @runtime_checkable decorator to Speaker. Without it,
isinstance(obj, Speaker) raises TypeError. Then write
solve(order: list[str]) -> list[str].
Leave Duck, Robot, Rock, REGISTRY and the speak signature as they
are. For each name in order, first to last, add one string to the result list:
- Look up its factory in
REGISTRY. If the name is not there, add"<unknown>"and go on to the next name. - Call the factory to build a new object.
- If
isinstance(obj, Speaker)is true, add the result ofobj.speak(). Otherwise add"<silent>".
The annotation on REGISTRY says every factory returns object, so mypy cannot tell which
class you get back. The isinstance check tells mypy the object is a
Speaker, so obj.speak() type-checks and returns a str.
Example
solve(["robot", "rock", "Duck", "duck"])
# ["beep", "<silent>", "<unknown>", "quack"]
"Duck" is unknown because the registry key is lowercase.
Edge cases
- Keys are case-sensitive.
- Repeated names give repeated results. Return one result per input name.
- An empty list returns
[].
At runtime, isinstance checks only that the object has an attribute called
speak. It does not check the arguments or the return type, so an object with
speak = 42 would pass. Only mypy, reading the annotations, checks the
signature.
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.