2017-12-25 11 views
1

私は、値に上限と下限があることを表現するための汎用クラスを作成しようとしています。mypyと比較可能な型

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

どうやら入力モジュールは、(それがlooks likeComparableを追加すると、将来的に起こるかもしれないが)、私はこれを表現することはできません:

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は、と文句を言い。

オブジェクトには__eq____lt__のメソッドがあることを確認するだけで十分だと思います(少なくとも私の場合)。現在のところ、Pythonでこの要件を表現する方法はありますか?

答えて

2

もう少し研究を重ねると、解決策が見つかりました:プロトコル。それらは完全に安定していません(まだ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) 
関連する問題