Dan*_*ats 4 python type-hinting python-3.x mypy
假设我有一个将字典作为参数的函数:
def f(d: dict) -> None:
x = d["x"]
print(x)
Run Code Online (Sandbox Code Playgroud)
我可以指定这本字典必须有"x"mypy的键吗?我正在寻找类似于typescript 的 interface 的东西,而无需更改d为类。
我不想更改d为类的原因是因为我正在修改一个大型现有代码库以添加mypy类型检查并且该字典在许多地方使用。如果我必须将所有实例更改为d["x"],我将不得不修改大量代码d.x。
从 Python 3.8 开始,您可以使用typing.TypedDict,根据PEP 589添加。对于较旧的 Python 版本,您可以使用该typing-extensions包
请注意,PEP 确实承认更好的选择是为此用例使用数据类,但是:
数据类是解决此用例的一种较新的替代方案,但仍有许多现有代码是在数据类可用之前编写的,尤其是在大型现有代码库中,类型提示和检查已被证明是有帮助的。
因此,更好的答案是考虑不同的数据结构,例如命名元组或数据类,您可以在其中指定类型具有的属性。这就是打字稿声明所做的,真的:
该
printLabel函数有一个参数,它要求传入的对象具有称为label字符串类型的属性。
Python 属性在道德上等同于 Typescript 对象属性。Typescript 对象表示法和 Python 字典有很多共同点,这可能会混淆问题,但是在尝试将概念映射到 Python 时,您不应将 Typescript 对象声明视为类以外的任何东西。
看起来像这样:
from dataclasses import dataclass
@dataclass
class SomeClass:
x: str
def f(sc: SomeClass) -> None:
x = sc.x
print(x)
Run Code Online (Sandbox Code Playgroud)
也就是说,你可以typing.TypedDict在这里使用:
from typing import TypedDict
class SomeDict(TypedDict):
x: str
def f(d: SomeDict) -> None:
x = d['x']
print(x)
Run Code Online (Sandbox Code Playgroud)
TypeDict声明中的键要么都是必需的,要么都是可选的(当您total=False在声明上设置时);您必须使用继承来生成带有一些可选键的类型,请参阅链接的文档。请注意,TypedDict 当前存在混合可选和必需键的问题;typing-extensions即使在使用 Python 3.8 时,您也可能希望使用该包来获取 Python 3.9 版本(修复了此问题)作为向后移植。只需使用from typing_extensions import TypedDict而不是上述from typing ...导入,typing-extensions包在适当的时候回退到标准库版本。