可比类型的mypy(Comparable types with mypy)

2019-09-29 23:25发布

我试图创建一个通用类来表达的值有上限和下限,并执行这些界限。

from typing import Any, Optional, TypeVar

T = TypeVar("T")

class Bounded(object):
    def __init__(self, minValue: T, maxValue: T) -> None:
        assert minValue <= maxValue
        self.__minValue = minValue
        self.__maxValue = maxValue

然而,mypy抱怨说:

error: Unsupported left operand type for <= ("T")

显然,输入模块不允许我表达这个(虽然它看起来像添加Comparable在将来可能发生的)。

我认为这将是足够的检查有对象__eq____lt__方法(我使用的情况下,至少)。 有没有什么办法来表达目前在Python这一规定,使Mypy会理解呢?

Answer 1:

更多的研究之后,我发现了一个解决方案:协议。 因为它们不是完全稳定(但Python的3.6),他们必须从进口typing_extensions模块。

import typing
from typing import Any
from typing_extensions import Protocol
from abc import abstractmethod

C = typing.TypeVar("C", bound="Comparable")

class Comparable(Protocol):
    @abstractmethod
    def __eq__(self, other: Any) -> bool:
        pass

    @abstractmethod
    def __lt__(self: C, other: C) -> bool:
        pass

    def __gt__(self: C, other: C) -> bool:
        return (not self < other) and self != other

    def __le__(self: C, other: C) -> bool:
        return self < other or self == other

    def __ge__(self: C, other: C) -> bool:
        return (not self < other)

现在,我们可以定义我们的类型:

C = typing.TypeVar("C", bound=Comparable)

class Bounded(object):
    def __init__(self, minValue: C, maxValue: C) -> None:
        assert minValue <= maxValue
        self.__minValue = minValue
        self.__maxValue = maxValue

而Mypy是幸福的:

from functools import total_ordering

@total_ordering
class Test(object):
    def __init__(self, value):
        self.value = value
    def __eq__(self, other):
        return self.value == other.value
    def __lt__(self, other):
        return self.value < other.value

FBounded(Test(1), Test(10))
FBounded(1, 10)


文章来源: Comparable types with mypy