包含命名元组的列表的类型提示

5

我在这里阅读了一篇关于命名元组类型提示的文章,但是它只涉及到命名元组。

是否有可能为包含namedtupleList创建类型提示?

例如:

firefoxprofile = namedtuple("Profile", ["Name", "Path", "isRelative", "Default"])

# Will contain a list of tuples that represent the firefox profiles.
ffprofiles = [] # -- how would I write the type hint?
ffprofiles.append(Profile(Name='Jason', Path='Profiles/er5rtak4.Jason', isRelative='1', Default=None))
ffprofiles.append(Profile(Name='Sarah', Path='Profiles/23mvfqcj.Sarah', isRelative='1', Default=None))

我尝试过:
ffprofiles = List[namedtuple("Profile", ["Name", "Path", "isRelative", "Default"])]

但是当我尝试使用该语法更新ffprofiles = []行时,它不起作用,并出现异常:

TypeError: descriptor 'append' requires a 'list' object but received a 'Profile'

3
List[firefoxprofile] - Aran-Fey
没关系,就像Aran说的那样,它是 List[firefoxprofile]。对我来说可以工作。 - timgeb
@timgeb - 你能否发布一个完整的答案,说明你如何使用类型提示声明List?也许我没有正确地声明List - user9814172
@Sveta List[firefoxprofile] -> typing.List[__main__.Profile]。你的错误在其他地方。 - timgeb
@timgeb - 当我正常声明一个List,即ffprofiles = []时,它可以工作。 - user9814172
1个回答

10

List[]类型中,不需要拼写出命名元组的名称,只需引用类型名称即可:

List[firefoxprofile]
将类型提示放在冒号后,但在赋值时的等号=之前,遵循PEP 526 变量注释语法规则:
ffprofiles: List[firefoxprofile] = []

这将ffprofiles设置为一个空列表,并告诉任何类型提示检查器该列表的内容必须是firefoxprofile类型的实例。如果你想在列表中提供一些初始配置文件,只需在列表文本中包含它们,无需在后面附加它们。

您将namedtuple()生成的类赋值给名称firefoxprofile,因此您的其余代码将使用该名称引用它,而不是使用名称Profile。但是,您可能还希望将namedtuple()的结果分配给作为第一个参数传递的相同名称,以便Profile = namedtuple('Profile', ...)

然而,您可能还想使用typing.NamedTuple 类来定义您的命名元组类型;您链接的帖子覆盖了这个问题,但这里应用于您的示例:

from typing import Optional, NamedTuple, List

class FirefoxProfile(NamedTuple):
    name: str
    path: str
    is_relative: bool
    default: Optional[str]

ffprofiles: List[FirefoxProfile] = [
    FirefoxProfile('Jason', 'Profiles/er5rtak4.Jason', True, None),
    # ... and more
]
定义一个继承自typing.NamedTuple的类与使用namedtuple()函数具有相同的结果,只不过语法更加简洁,可以为字段添加类型,并且可以选择添加docstring和其他属性或方法(几乎任何非类型提示属性或命名元组方法都可以使用)。现在类型提示机制将更多地了解所期望的内容。不仅现在清楚列表将包含哪种类型的实例,以上还记录了命名元组类支持哪些属性以及每个属性的类型。我根据我的猜测来指定它们的类型。这里使用了Python的PEP-8风格约定,因此命名元组属性都使用小写带下划线(“snake_case”),而不是CamelCase。后者真正应该只用于类名。

谢谢您,不知道为什么我的问题被投了两次反对票。 - user9814172
1
@Sveta:我也无法告诉你为什么,因为我还不能读心。也许你的问题缺少分享你的研究,或者那些投票的人认为在发布之前你应该对Python的类型提示语法进行更多的研究。如果你确实做了这项研究,请确保在你的帖子中分享它。 - Martijn Pieters
好的建议!下次会更加努力。 - user9814172

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接