为包含namedtuple的列表键入提示

时间:2018-06-21 15:06:06

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

我正在读here,但这是有关namedtuple的类型提示。

是否可以为包含List的{​​{1}}创建类型提示?

例如:

namedtuple

我尝试过:

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 = []

1 个答案:

答案 0 :(得分:1)

您不会拼写命名的元组,而在您的List[]类型中引用只是类型的名称

List[firefoxprofile]

将类型提示放在冒号之后,但在=之前放在之前,PEP 526 Variable Annotations语法如下:

ffprofiles: List[firefoxprofile] = []

这会将ffprofiles设置为一个空列表,并告诉所有类型提示检查器该列表的内容必须是firefoxprofile类型的实例。如果要在该列表中提供一些初始配置文件,只需将它们包括在列表文字中,而无需在之后附加它们。

您将namedtuple()生成的类分配给名称firefoxprofile,因此其余代码将用来引用它,而不是名称Profile。不过,您可能希望将namedtuple()的结果分配为与第一个参数传入的名称相同的名称,所以Profile = namedtuple('Profile', ...)

但是,您可能还想使用typing.NamedTuple class来定义键入的命名元组。您链接到的帖子对此进行了介绍,但此处将其应用于您的示例:

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()函数具有相同的结果,除了语法更简洁外,您可以为字段添加类型,并且可以选择添加文档字符串和其他属性或方法(几乎所有不是类型提示属性或namedtuple方法的东西)。

现在,类型提示机制将对预期的内容了解更多。现在不仅可以清楚列表将包含的实例类型,而且上面还记录了命名元组类支持的属性以及这些属性分别具有的类型。我对这些类型可能是什么做了一些有根据的猜测。我在这里也使用Python的PEP-8样式约定来命名,因此命名的元组属性全部使用lowercase_with_underscores(“ snake_case”)而不是CamelCase。后者实际上应该仅用于类名。