typing
удобно предоставляет общую версию collections.MutableSequence
, поэтому что-то с эффектом:
import typing
T = typing.TypeVar('T')
class HomogeneousList(typing.MutableSequence[T]):
def __init__(self, iterable: typing.Iterable[T]=()) -> None:
self._data: typing.List[T] = []
self._data.extend(iterable)
@typing.overload
def __getitem__(self, index: int) -> T: ...
@typing.overload
def __getitem__(self, index: slice) -> HomogeneousList[T]: ...
def __getitem__(self, index):
return self._data[index]
@typing.overload
def __setitem__(self, index: int, item: T) -> None: ...
@typing.overload
def __setitem__(self, index: slice, item: typing.Iterable[T]) -> None: ...
def __setitem__(self, index, item):
self._data[index] = item
def __delitem__(self, index: typing.Union[int, slice]) -> None:
del self._data[index]
def __len__(self) -> int:
return len(self._data)
def insert(self, index: int, item: T) -> None:
self._data.insert(index, item)
string_list = HomogeneousList[str]()
string_list.append('foo')
string_list.append(42)
int_list = HomogeneousList[int]()
int_list.append(42)
int_list.append('foo')
Теперь mypy
дает следующие ошибки:
test.py:36: error: Argument 1 to "append" of "MutableSequence" has incompatible type "int"; expected "str"
test.py:41: error: Argument 1 to "append" of "MutableSequence" has incompatible type "str"; expected "int"
Есть некоторые хитрые аспекты ввода __getitem__
и т. Д., Поскольку они также принимают slice
объекты, но не ужасно.
Обратите внимание, это полезно, потому что если вы просто попытаетесь сделать:
class HomogeneousList(collections.abc.MutableSequence, typing.Generic[T]):
....
MyPy, по крайней мере, не выдает ошибку для добавления.AFAIKT, вам нужно было бы явно добавить: '
def append(self, item: T) -> None:
self._data.append(item)
Какой тип удаления из утилиты collections.abc.MutableSequence
с самого начала убирает.В любом случае, к счастью, набор предоставляет готовые версии всех этих программ из коробки!
Обратите внимание, что вы можете использовать их в общем виде, как я покажу, но вы также можете сделать что-то вроде:
class StringList(HomogeneousList[str]):
pass
mylist = StringList([1,2,3]) # mypy error
mylist = StringList('abc') # no error
mylist.append('foo') # no error
mylist.append(42) # mypy error