我用 Python 3.5 编写了这段代码:
from collections import namedtuple
attributes = ('content', 'status')
Response = namedtuple('Response', attributes)
当我运行 Mypy 类型检查器来分析此代码时,它引发了错误:
错误:列表或元组文字应作为
的第二个参数namedtuple()
我尝试向
attributes
变量添加类型注释:
from typing import Tuple
attributes = ('content', 'status') # type: Tuple[str, str]
但它并没有修复引发的错误。
如果你想让 mypy 了解你的命名元组是什么样的,你应该从
NamedTuple
模块导入 typing
,如下所示:
from typing import NamedTuple
Response = NamedTuple('Response', [('content', str), ('status', str)])
然后,您可以像任何其他命名元组一样使用
Response
,只不过 mypy 现在可以理解每个单独字段的类型。如果您使用的是 Python 3.6,您还可以使用替代的基于类的语法:
from typing import NamedTuple
class Response(NamedTuple):
content: str
status: str
如果您希望动态改变字段并编写一些可以在运行时“构建”不同命名元组的东西,不幸的是,这在Python的类型生态系统中是不可能的。 PEP 484 目前没有任何规定在类型检查阶段传播或提取任何给定变量的实际“值”。 以完全通用的方式实现这一点实际上非常具有挑战性,因此不太可能很快添加此功能(如果是的话,它可能会以更加有限的形式)。
mypy
问题跟踪器上的 issue 848,这永远不会实现(请参阅 GvR 的最后一条消息)。
虽然
# type: ignore
实际上会消除此警告,但它会产生其他问题,因此,如果可以的话,不要依赖于动态指定namedtuple的字段名称(即以迈克尔的答案提供的方式提供文字)。