Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python mypy设置字典键/接口_Python_Python 3.x_Type Hinting_Mypy - Fatal编程技术网

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,我已经更新了我的答案来反映这一点。