【问题标题】:mypy error: List or tuple literal expected as the second argument to namedtuple()mypy 错误:列表或元组文字应作为 namedtuple() 的第二个参数
【发布时间】:2017-06-19 19:20:41
【问题描述】:

我在 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 可以按原样使用。尝试解压元组,例如...a, b = Response('some content', 'some attr') --> print('%s; %s' % (a, b)).

标签: python python-3.x type-hinting mypy python-typing


【解决方案1】:

如果您希望 mypy 了解您的命名元组是什么样的,您应该从 typing 模块导入 NamedTuple,如下所示:

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 目前没有任何规定在类型检查阶段传播或提取任何给定变量的实际

以完全通用的方式实现此功能实际上非常具有挑战性,因此不太可能很快添加此功能(如果是的话,它可能会采用更有限的形式)。

【讨论】:

  • 不过,Python 3.6 的语法太漂亮了。
  • @JimFasarakisHilliard -- 这实际上可能在未来更重要! Guido 显然对修改 Python 本身很感兴趣,因此您可以以这种风格定义自定义类(无需所有 namedtuple 开销,也无需编写 __init__ 方法)——请参阅 python-ideas 邮件列表中的 this post,和一些后续的。讨论的部分灵感来自attrs library,这显然很受欢迎。
  • 啊,我记得看过那个帖子。虽然有 50 多个回复(如果我没记错的话),我从来没有彻底遵循它。由于我还没有看到 PEP 草案的帖子,我想我们正在等待,现在 :-)
  • 谢谢!很好的答案:)
【解决方案2】:

根据mypy 的问题跟踪器上的issue 848,这永远不会实现(请参阅 GvR 的最后一条消息)。

尽管# type: ignore 实际上确实使此警告静音,但它会产生其他问题,因此,如果可以的话,不要依赖于动态指定命名元组的字段名称(即按照迈克尔的回答提供的方式提供文字)。

【讨论】:

    猜你喜欢
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 2022-01-14
    • 1970-01-01
    • 2021-12-19
    • 1970-01-01
    相关资源
    最近更新 更多