[英]How can I hint that a type is comparable with typing
假设我想编写一个比较排序函数,我可以提示输入必须是带有Sequence[T]
的序列(或在这种情况下为MutableSequence[T]
)。
from typing import MutableSequence, T
def comparison_sort(s: MutableSequence[T]) -> None:
pass
然而,似乎没有一种开箱即用的方式来暗示T
必须具有可比性。 ( typing
时没有Comparable
或Ordered
或任何东西。)我怎样才能做到这一点? 我想避免指定一组特定的类型,如int
、 float
、 'str` 以便用户也可以暗示他们自己的类型是可比较的。
如评论中所述, Comparable
不是一种存在状态,它仅作为一对类型的描述符才有意义。 通常,排序函数使用同质类型,所以只要你不介意类型检查器只处理“支持<
某些类型”而不是“支持<
任意类型”的概念,你可以定义你的拥有Comparable
并与它绑定一个typing
TypeVar
。 方便的是, PEP484 (它定义了typing
提示)已经提供了一个例子来说明你如何做到这一点:
from abc import ABCMeta, abstractmethod
from typing import Any, TypeVar
class Comparable(metaclass=ABCMeta):
@abstractmethod
def __lt__(self, other: Any) -> bool: ...
CT = TypeVar('CT', bound=Comparable)
然后,您可以将其用于您的comparable_sort
定义:
def comparable_sort(s: MutableSequence[CT]) -> None:
请注意,我只需要定义__lt__
; 作为一项规则,Python 3 完全根据__lt__
实现自己的排序函数(它不使用任何其他丰富的比较器运算符,甚至不使用__eq__
) † ,因此以相同的方式设计自己的算法是个好主意,所以任何sorted
的东西都可以处理,你可以用同样的方式处理。
† :Python 2 最初在至少一个地方( heapq
)使用__le__
,但在 Python 3 时间范围内,它一直是故意的,始终如一的__lt__
用于内置函数和标准库,并且您的打字风格无论如何都是 Python 3-only。
此版本适用于当前的mypy
版本。
基于typing
回购中的线程: https ://github.com/python/typing/issues/59
from __future__ import annotations
from abc import abstractmethod
from typing import MutableSequence, Protocol, TypeVar
class Comparable(Protocol):
"""Protocol for annotating comparable types."""
@abstractmethod
def __lt__(self: CT, other: CT) -> bool:
pass
CT = TypeVar("CT", bound=Comparable)
def comparison_sort(s: MutableSequence[CT]) -> None:
pass
comparison_sort([1, 2, 3]) # OK
comparison_sort([1.0, 2.0, 3.0]) # OK
comparison_sort(["42", "420", "2137"]) # OK
comparison_sort([1, 2, "3"]) # mypy error
链接到 Github 要点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.