对于允许您仍然使用本机切片语法并保持静态类型兼容性的东西,您可以在序列周围使用轻量级包装器类:
from typing import Generic, Protocol, TypeVar
S = TypeVar('S', bound="ConcatSequence")
class CircularView(Generic[S]):
def __init__(self, seq: S) -> None:
self.seq = seq
def __getitem__(self, s: slice) -> S:
if s.start <= s.stop:
return self.seq[s]
else:
wrap = len(self.seq) % s.step if s.step else 0
return self.seq[s.start::s.step] + self.seq[wrap:s.stop:s.step]
lst = [0, 10, 20, 30, 40, 50, 60, 70]
print(CircularView(lst)[2:5]) # [20, 30, 40]
print(CircularView(lst)[5:2]) # [50, 60, 70, 0, 10]
print(CircularView(lst)[5:2:2]) # [50, 70, 0]
print(CircularView(lst)[5:3:2]) # [50, 70, 0, 20]
print(CircularView(lst)[4:3:3]) # [40, 70, 20]
带有可选的protocol 用于静态类型
class ConcatSequence(Protocol):
"""
A sequence that implements concatenation via '__add__'.
This protocol is required instead of using
'collections.abc.Sequence' since not all sequence types
implement '__add__' (for example, 'range').
"""
def __add__(self, other):
...
def __getitem__(self, item):
...
def __len__(self):
...
这个方法passes type checking with mypy。