如何解决让 Mypy 对固定/最大长度序列感到满意
在使用其他几种语言实现互操作层时,我遇到了如何表示固定长度和最大长度序列的问题。而对于 Python 来说,其他语言需要提供完整的类型信息并不重要。面向用户的 API 应如下所示:
@dataclass
class MyStruct:
name: bounded_str[12] # here 12 is a max length
data: sequence[int8,20] # here 20 is the max length
other_data: array[float32,10] # here 10 is a fixed length
现在我可以让它与普通的python一起工作没有问题。我让 sequence
和 array
生成 Annotated
类型如下:
class ArrayMeta(type):
def __getitem__(cls,tup):
if type(tup) != tuple or len(tup) != 2 or type(tup[1]) != int:
return TypeError("An array takes two arguments: a subtype and a constant length.")
return Annotated[Sequence[tup[0]],array(*tup)]
class array(Metaclass=ArrayMeta):
def __init__(self,subtype,length):
self.subtype = subtype
self.length = length
这使数据类具有完全可接受的 Annotated[Sequence[subtype],...]
,我可以使用 get_type_hints
检查注释并确定互操作所需的“真实”类型,生成验证器/序列化器等。
现在,当我们将 Mypy 引入混合时,问题就来了。 Mypy 无法将 array
类型识别为有效,这很公平。但是,到目前为止,我制作有效版本的任何尝试都被难住了,因为 Generic
不会采用值类型:
T = TypeVar('T')
V = TypeVar('V')
class MyArray(Protocol,Generic[T,V]):
def __getitem__(self,key: int) -> T: ...
def __len__(self):
return V
a: MyArray[int,5] = [0,1,2,3,4]
>>> TypeError: Parameters to generic types must be types. Got 5.
有没有办法让 Mypy 对这些 sequence
和 array
类型感到满意?
解决方法
mypy 中没有“最大长度”检查,这意味着集合在运行时已填充,因此在此之前无法检查。
唯一可以用固定长度定义的结构是 Tuple
并且你必须定义每个元素,例如一个 4 个整数的元组看起来像这样:
from typing import Tuple
data: Tuple[int,int,int]
,
您可以使用 Literal[5]
,请参阅 typing.Literal:
一种类型,可用于向类型检查器指示相应的变量或函数参数具有与提供的文字(或多个文字之一)等效的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。