Joh*_*die 15 python type-hinting python-3.x mypy
我正在给Python typing模块一个镜头.
我知道指定List以下*的长度是有效的:
List[float, float, float] # List of 3 floats <-- NOTE: this is not valid Python
Run Code Online (Sandbox Code Playgroud)
是否有更长的名单的简写?如果我想将它设置为10个花车怎么办?
List[float * 10] # This doesn't work.
Run Code Online (Sandbox Code Playgroud)
如果这是可能的,任何想法,这将是方便的.
*注意:事实证明Sequence[]以这种方式向(及其子类)提供多个参数当前不是有效的Python.此外,目前不可能以这种方式Sequence使用typing模块指定长度.
Zaf*_*ffy 43
typing.Annotated在这里可以派上用场。它允许您指定任意元数据来键入提示:
Annotated[list[float], 3]
Run Code Online (Sandbox Code Playgroud)
新的Annotated?这是文档的片段:
如果一个库(或工具)遇到 typehint
Annotated[T, x]并且对于元数据没有特殊的逻辑x,它应该忽略它并简单地将类型视为T.
值得注意的是,对于此类事情mypy有一个未完成的请求(截至 2022 年 11 月开放)。同时,考虑Annotated开发人员的可读性,而不是自动检查(除非您开发检查工具)。
你不能 列表是可变的,可变长度的结构。如果需要固定长度的结构,请改用元组:
Tuple[float, float, float, float, float, float, float, float, float, float]
Run Code Online (Sandbox Code Playgroud)
更好的方法是使用具有索引和命名属性的命名元组:
class BunchOfFloats(NamedTuple):
foo: float
bar: float
baz: float
spam: float
ham: float
eggs: float
monty: float
python: float
idle: float
cleese: float
Run Code Online (Sandbox Code Playgroud)
对于固定长度的数据结构,列表只是错误的数据类型。
小智 6
当也面临同样的问题时,我很高兴看到Martijn Pieters 的回答。因为我想要一种“快速”和“简单”的方法来解决这个问题。
所以我首先尝试了这里列出的其他建议。
注意:我使用 VSCode 和 Pylance 作为语言服务器
扎菲的回答是我最喜欢的
def demystify(mystery: Annotated[Tuple[int], 6]):
a, b, c, d, e, f = mystery
print(a, b, c, d, e, f)
Run Code Online (Sandbox Code Playgroud)
该函数的提示如下所示:此外,我还收到该行的demystify: (mystery: Tuple[int]) -> None
Pylance 错误Tuple size mismatch: expected 6 but receiveda, b, c, d, e, f = mystery
接下来我尝试了balu 在Martijn Pieters 答案Tuple[6 * (int, )]的评论中提到的
def demystify(mystery: Tuple[6 * (int,)]):
a, b, c, e, f, g = mystery
print(a, b, c, e, f, g)
Run Code Online (Sandbox Code Playgroud)
导致与之前相同的 Pylance 错误。该函数的提示是这样的:demystify: (mystery: Tuple[Tuple[Type[int], ...]]) -> None
回到写下预期长度:
def demystify(mystery: Tuple[int, int, int, int, int, int]):
a, b, c, e, f, g = mystery
print(a, b, c, e, f, g)
Run Code Online (Sandbox Code Playgroud)
这解决了 Pylance 错误,并给了我一个“清晰”的函数提示:demystify: (mystery: Tuple[int, int, int, int, int, int]) -> None
但就像约翰·布罗迪一样,我对这个解决方案并不满意。
现在回到最初不需要的答案:
class MysteryType(NamedTuple):
a: int
b: int
c: int
d: int
e: int
f: int
g: int
def demystify(mystery: MysteryType):
print(*mystery)
Run Code Online (Sandbox Code Playgroud)
函数提示现在看起来更加神秘:demystify: (mystery: MysteryType) -> None但是创建一个新的 MysteryType 为我提供了我需要的所有信息:(a: int, b: int, c: int, d: int, e: int, f: int, g: int)
我还可以在其他方法和函数中使用 MysteryType,而无需计算类型提示。
因此,长话短说,解释一下 Python 的禅宗:
NamedTuples 是一个非常棒的想法——让我们多做一些这样的事情吧!
到目前为止,只有元组支持指定固定数量的字段,并且对于固定数量的重复没有捷径。
这是typing模块的定义和文档字符串:
class Tuple(tuple, extra=tuple, metaclass=TupleMeta):
"""Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
Example: Tuple[T1, T2] is a tuple of two elements corresponding
to type variables T1 and T2. Tuple[int, float, str] is a tuple
of an int, a float and a string.
To specify a variable-length tuple of homogeneous type, use Tuple[T, ...].
"""
__slots__ = ()
def __new__(cls, *args, **kwds):
if _geqv(cls, Tuple):
raise TypeError("Type Tuple cannot be instantiated; "
"use tuple() instead")
return _generic_new(tuple, cls, *args, **kwds)
Run Code Online (Sandbox Code Playgroud)
由于列表是可变的,可变长度的类型,因此使用类型声明来指定固定大小没有任何意义。
| 归档时间: |
|
| 查看次数: |
4423 次 |
| 最近记录: |