Python mypy设置字典键/接口
假设我有一个以字典为参数的函数:Python mypy设置字典键/接口,python,python-3.x,type-hinting,mypy,Python,Python 3.x,Type Hinting,Mypy,假设我有一个以字典为参数的函数: def f(d: dict) -> None: x = d["x"] print(x) 我是否可以指定此词典必须具有mypy的键“x”?我正在寻找类似的东西,但不将d更改为类 我不想将d更改为类的原因是,我正在修改一个大型的现有代码库,以添加mypy类型检查,并且该字典在许多地方都使用。如果我必须将d[“x”]的所有实例更改为d.x从您可以使用的Python 3.8开始,我将不得不修改大量代码,并根据添加。对于较旧的Python版本,可以
def f(d: dict) -> None:
x = d["x"]
print(x)
我是否可以指定此词典必须具有mypy的键“x”
?我正在寻找类似的东西,但不将d
更改为类
我不想将
d
更改为类的原因是,我正在修改一个大型的现有代码库,以添加mypy
类型检查,并且该字典在许多地方都使用。如果我必须将d[“x”]
的所有实例更改为d.x
从您可以使用的Python 3.8开始,我将不得不修改大量代码,并根据添加。对于较旧的Python版本,可以使用
请注意,PEP确实承认更好的选择是将数据类用于此用例,但是:
数据类是解决此用例的较新的替代方案,但在数据类可用之前仍有许多现有代码编写,特别是在大型现有代码库中,类型暗示和检查已被证明是有用的
>更好的答案是考虑不同的数据结构,例如命名元组或数据包,在其中可以指定类型具有的属性。这就是typescript声明的作用,实际上:
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)
也就是说,您可以在此处使用键入.TypedDict
:
from typing import TypedDict
class SomeDict(TypedDict):
x: str
def f(d: SomeDict) -> None:
x = d['x']
print(x)
TypeDict
声明中的键要么全部是必需的,要么全部是可选的(当您在声明中设置total=False
时);您必须使用继承来生成带有一些可选键的类型,请参阅链接的文档。请注意,TypedDict
;即使在使用Python3.8时,您也可能希望使用typingextensions
包来获取Python3.9版本(它修复了这个问题)作为一个后端口。只需使用from typing\u extensions import TypedDict
而不是上面的from typing…
import,typing extensions
包在适当的时候会返回到标准库版本。Mypy通过提供一个类型扩展PEP 484。这允许指定dict类型的特定属性。在您的情况下,您可以执行以下操作:
from mypy_extensions import TypedDict
# you can also do HasX = TypedDict('HasX', {'x': str})
class HasX(TypedDict):
x: str
def f(x: HasX) -> None:
reveal_type(d["x"]) # error: Revealed type is 'builtins.str'
这不是真的,mypy有
TypedDict
,如@ethanhsanswer@Gricey:的确如此。这是一个特定于mypy的扩展,我一直坚持只针对Python的官方类型规范。更新:TypedDict
在Python3.8中:@alkasm:yup,我已经更新了我的答案来反映这一点。