Mic*_*eno 5 python python-typing pylance
我有一个排序的链表
class SortedLinkedList:
# ...
def insert(self, value: int):
# ...
if node.value > value:
self.add_before(node, value)
# ...
Run Code Online (Sandbox Code Playgroud)
我想将 a 可以保存的值类型概括为Node从仅s 到通过实现魔术方法int重载运算符的任何对象。>__gt__()
在其他语言中,我会通过使用 来实现这一点Interface,但 Python 显然没有类似的东西。我已经看到通过使用抽象类来伪造接口的建议,例如
class Sortable(ABC):
@abstractmethod
def __gt__(self, other) -> bool:
pass
class SortedLinkedList:
# ...
def insert(self, value: Sortable, node: Node):
# ...
Run Code Online (Sandbox Code Playgroud)
问题是这种方法需要扩展和使用 的子类,这意味着不能使用Sortable已经具有整数等功能的类型>
linkedlist.insert(5) # Pylance red squiggles
Run Code Online (Sandbox Code Playgroud)
Argument of type "Literal[5]" cannot be assigned to
parameter "value" of type "Sortable" in function "insert"
"Literal[5]" is incompatible with "Sortable" Pylance(reportGeneralTypeIssues)
Run Code Online (Sandbox Code Playgroud)
我知道,鉴于 Python 的动态鸭子类型和隐式样式,接口在运行前不是必需的。我不是粉丝,并且选择使用可用的工具(如打字和Pylance)来实现严格类型化的开发人员体验。
我也不打算使用像.hasattr(value, '__gt__'). 我希望它在类型系统/语言服务器/IDE 级别上注册,因为表达性、可读性和 IDE 智能感知是严格类型的主要好处。
有什么办法可以实现这一点吗?
您要找的是typing.Protocol.
class Sortable(Protocol):
def __gt__(self, other) -> bool: ...
Run Code Online (Sandbox Code Playgroud)
这样,任何定义的类都__gt__将被检测为 的隐式子类型Sortable。请注意,在 Python >= 3.8 中,您可能需要进行other定位:
class Sortable(Protocol):
def __gt__(self, other, /) -> bool: ...
Run Code Online (Sandbox Code Playgroud)
__gt__这是因为类型检查器可能不会像处理普通方法那样处理 dunder 方法,因此期望参数可能需要通过关键字调用。添加/告诉检查器该__gt__参数永远不需要通过关键字传递。相反,如果参数仅通过关键字传递,请相应地标记协议的方法:
class Something(Protocol):
def method(self, *, name) -> str: ...
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
334 次 |
| 最近记录: |