tah*_*ith 12 python python-3.x
假设我想写一个比较排序函数,我可以提示输入必须是一个序列 with Sequence[T](或MutableSequence[T]在这种情况下)。
from typing import MutableSequence, T
def comparison_sort(s: MutableSequence[T]) -> None:
pass
Run Code Online (Sandbox Code Playgroud)
然而,似乎没有一种开箱即用的方式来暗示T必须具有可比性。(似乎没有Comparable或Ordered任何东西typing。)我怎样才能做到这一点?我想避免指定一组特定的类型,例如int, float, 'str` 以便用户也可以暗示他们自己的类型是可比较的。
Sha*_*ger 12
正如评论中所指出的,Comparable它不是一种存在状态,它仅作为一对类型的描述符才有意义。通常,排序函数使用同构类型,因此只要您不介意类型检查器只处理“支持<某些类型”而不是“支持<任意类型”的概念,您就可以定义自己的Comparable和绑定了typing TypeVar它。方便的是,PEP484(定义typing提示)已经提供了一个示例,说明您将如何执行此操作:
from abc import ABCMeta
from typing import Any, TypeVar
class Comparable(metaclass=ABCMeta):
@abstractmethod
def __lt__(self, other: Any) -> bool: ...
CT = TypeVar('CT', bound=Comparable)
Run Code Online (Sandbox Code Playgroud)
然后,您可以将其用于您的comparable_sort定义:
def comparable_sort(s: MutableSequence[CT]) -> None:
Run Code Online (Sandbox Code Playgroud)
请注意,我只需要__lt__被定义;通常,Python 3 完全根据__lt__(它不使用任何其他丰富的比较器运算符,甚至不使用__eq__)† 来实现自己的排序功能,因此以相同的方式设计自己的算法是个好主意,所以任何事情sorted可以处理,你可以用同样的方式处理。
†:Python 2 最初__le__至少在一个地方 ( heapq) 使用,但它一直有意地、始终如一地__lt__用于 Python 3 时间范围内的内置函数和标准库,而且您的输入风格无论如何都只适用于 Python 3。
此版本适用于当前mypy版本。
基于typingrepo 中的线程: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
Run Code Online (Sandbox Code Playgroud)
链接到 Github 要点。