gpt4 book ai didi

python - 在 python 3.6 中通过属性表示法表示字典键时的类型提示

转载 作者:行者123 更新时间:2023-12-01 09:16:54 25 4
gpt4 key购买 nike

Accessing dict keys like an attribute? 中的第一个答案为例:

class AttrDict(dict):
def __init__(self, *args, **kwargs):
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self

以及一个返回的函数:

def dict_to_attrdict(somedict):
return AttrDict(**somedict)

分配为:

data = dict_to_attrdict(mydict)

在给定以下约束的情况下,为将通过 mypy 检查的类和函数添加类型提示的正确方法是什么:

  • 字典键始终是 str
  • 字典值必须是动态的,并由 Any 表示,因为它们各不相同,我不希望单独键入每个值,即一些 strList [dict[str, List]], Dict[str, str], Dict[str, List]

最佳答案

您可以通过执行以下操作对类和函数定义本身进行类型检查:

from typing import Dict, Any

class AttrDict(Dict[str, Any]):
def __init__(self, *args: Any, **kwargs: Any) -> None:
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self

def dict_to_attrdict(some: Dict[str, Any]) -> AttrDict:
return AttrDict(**some)

继承自 Dict[X, Y] 与运行时仅继承 dict 没有什么不同,但它为 mypy 提供了所需的额外元数据。

但是,您实际上无法以类型安全的方式使用 AttrDict 实例:mypy 始终会将 my_attrdict.foo 之类的内容标记为错误。

这是因为不可能静态地确定在所有情况下 AttrDict 中将出现哪些字段 - mypy 不知道 AttrDict 中到底存在什么。由于 mypy 无法判断像 my_attrdict.foo 这样的事情是否实际上是安全的,因此它倾向于保守的一面,并决定认为这是不安全的。

您有两种不同的选择来解决此问题。首先,如果您确实希望尽可能保持 AttrDict 动态,您可以告诉 mypy 假设该类型是任意动态类型,如下所示:

from typing import Dict, Any, TYPE_CHECKING

if TYPE_CHECKING:
AttrDict = Any
else:
class AttrDict(dict):
def __init__(self, *args, **kwargs) -> None:
super(AttrDict, self).__init__(*args, **kwargs)
self.__dict__ = self

def dict_to_attrdict(some: Dict[str, Any]) -> AttrDict:
return AttrDict(**some)

TYPE_CHECKING 是一个在运行时始终为 False 的值,但被 mypy 视为始终为 True。最终效果是 mypy 将只考虑 if/else 的 'if' 分支,并忽略 'else' 分支中的任何内容:我们现在已经告诉 mypy AttrDict 是一个类型Any 的别名:与Any 完全相同。然而,在运行时,我们总是陷入“else”分支并像以前一样定义类。

这种方法的主要缺点是我们实际上没有从使用静态类型中获得任何值(value)。我们可以为 dict_to_attrdict 添加一点安全性,因为我们现在可以强制键必须是字符串,但仅此而已。

第二个选择是利用 mypy 的优势并重写代码以实际使用类。因此,我们将摆脱 AttrDict 并实际上使用设置其字段的类。

这可以让 mypy 了解存在哪些字段,它们的类型是什么,等等。这需要更多的前期工作,但好处是 mypy 能够为您的代码的正确性提供更有力的保证。

如果您发现实际上定义一堆带字段的类很乏味,请尝试使用新的“dataclasses”模块(如果您使用的是 Python 3.7)或第 3 方“attrs”模块。我相信 mypy 最近添加了对两者的支持。

如果您想使用数据类,您可能必须等到 mypy 0.620 在下周二发布 - 我不记得该功能是否已包含在 mypy 0.600 或 mypy 0.610 中。

关于python - 在 python 3.6 中通过属性表示法表示字典键时的类型提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51165451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com