python - 如何确保两个参数具有可比性?
问题描述
我实现了一个类似于这个简化版本的 Interval 类:
class Interval:
def __init__(self, left, right):
assert left <= right
self.left = left
self.right = right
def intersect(self, other: Interval) -> Optional[Interval]:
if other.left < self.left:
self, other = other, self
# self starts first
if self.right < other.left:
return None
return Interval(other.left, min(self.right, other.right))
我现在想知道在这两种情况下如何添加好的类型注释。我的主要问题是关于构造函数:我怎样才能确保左右是可比较的?它们可以是字符串、数字或任何实现__le__
. mypy可以检查吗?
解决方案
Python 的类型注解不足以表达这一点。
您可以编写一个协议来指定比较方法的存在,但没有办法指定对象可以相互比较。此外, mypy 不理解functools.total_ordering
,因此任何使用它的类都会出现虚假错误。
(另外,每个类在技术上都有一套完整的 6 个比较方法,由于object
's 比较方法是如何从其 C 级tp_richcompare
插槽生成的细节,但 mypy 不这么认为。)
(不足的)协议看起来像
class Comparable(typing.Protocol):
def __eq__(self, other): ...
def __ne__(self, other): ...
def __lt__(self, other): ...
def __le__(self, other): ...
def __gt__(self, other): ...
def __ge__(self, other): ...
请注意,我没有在方法上添加任何注释。这是故意的——“明显”的注释def __eq__(self, other: Comparable) -> bool
是错误的。
比较方法应该接受任意其他对象,NotImplemented
如果它们不识别其他对象则返回。这意味着other
除了object
. 此外,mypy 不理解Union[bool, type(NotImplemented)]
. 此外,在某些情况下,比较可能会返回 abool
或以外的结果NotImplemented
- 例如,比较两个 NumPy 标量将返回一个numpy.bool_
不是布尔值的实例,但大多数情况下都像一个。
推荐阅读
- amazon-web-services - 在弹性 beantalk 和 kubernetes 之间分配的应用程序负载均衡器
- android - 如何使用 Flutter Slider 设置自定义数据模型
- git - 为什么 git merge 删除文件而不是移动它们?
- python - 如何在 pyqt5 中缓慢移动标签?我希望标签自动移动(一段时间为真?)
- html - html 停止 iframe 向下推送内容
- android - android上的usb大容量存储
- ios - Safari 远程调试看不到 iPhone
- three.js - 如何在 Three.js 中操作几何与网格?
- javascript - Angular 8 - 将表单数据输入加载到前一个组件中
- c++ - 为什么我得到浮点异常