在下面的Python 3.5代码中,我想使用小于运算符(<
)来比较两个通用值。如何在T上声明约束以支持__lt__
?
from typing import *
import operator
T = TypeVar('T')
class MyList(Generic[T]):
class Node:
def __init__(self, k:T) -> None:
self.key = k
self.next = None # type: Optional[MyList.Node]
def __init__(self) -> None:
self.root = None # type: Optional[MyList.Node]
def this_works(self, val:T) -> bool:
return self.root.key == val
def not_works(self, val:T) -> bool:
return operator.lt(self.root.key, val)
我正在使用Mypy键入支票,并且not_works
上的消息显示失败,并显示以下消息:
$ mypy test.py
test.py: note: In member "not_works" of class "MyList":
test.py:20: error: Unsupported left operand type for < ("T")
其他语言支持对T的约束。
在C#中:class MyList<T> where T:IComparable<T>
在Java中:class MyList<T extends Comparable<? super T>>
答案 0 :(得分:3)
您可以通过将额外参数bound
传递给TypeVar
来实现目标,如PEP484中所述:
类型变量可以使用
bound=<type>
指定上限。这意味着类型变量替换(显式或隐式)的实际类型必须是边界类型的子类型。一个常见的例子是Comparable类型的定义,它足以捕获最常见的错误:
来自上述PEP的示例代码:
from typing import TypeVar
class Comparable(metaclass=ABCMeta):
@abstractmethod
def __lt__(self, other: Any) -> bool: ...
... # __gt__ etc. as well
CT = TypeVar('CT', bound=Comparable)
def min(x: CT, y: CT) -> CT:
if x < y:
return x
else:
return y
min(1, 2) # ok, return type int
min('x', 'y') # ok, return type str
在mypy的最新版本(经过0.521验证)中,正确处理了上述情况。