Source From Here
QuestionLet's say I have a simple function like this:
- def handle(d: People) -> None:
- print(f"{d.name}/{d.age}")
HowTo
This is exactly what Protocols are for. In short, Protocols let you use structural instead of nominal subtyping. With nominal subtyping, type A is a subtype of B if A explicitly inherits or extends B. With structural subtyping, type A is a subtype of B if it has the same method and attribute "signatures" as B (with some restrictions).
For example:
- from typing import Protocol
- class People(Protocol):
- name: str
- age: int
- class P1:
- def __init__(self) -> None:
- self.name = 'John'
- self.age = 1
- class P2:
- def __init__(self) -> None:
- self.name = 'Ken'
- self.age = 56
- self.extra_attr = 'test'
- class P3:
- def __init__(self) -> None:
- self.name = 'Mary'
- class P4:
- def __init__(self) -> None:
- self.age = 99
- def handle(d: People) -> None:
- print(f"{d.name}/{d.age}")
- handle(P1())
- handle(P2())
- # "P3" is missing following "People" protocol member: age
- handle(P3())
- # "P4" is missing following "Device" protocol member: name
- handle(P4())
You can also find slightly more complex examples of using Protocols in typeshed, the repository of type hints for the Python standard library.
Though, I suppose this all matters only if you actually intend on using static analysis in your code. If not, you could maybe do something simpler and just define a custom type alias to Any, document what that alias is "supposed" to mean, and use that alias instead of a full-fledged protocol. That alias would be almost completely useless for the purposes of static analysis/autocompletion tools/etc, but humans generally have no issues reading comments.
Supplement
* Is there a way to make flake8 check for type hints in the source
沒有留言:
張貼留言