在 Dataclass 中创建 DefaultDict 时遇到问题

Bil*_*ll 17 python-3.x defaultdict python-dataclasses

我在使用新的 defaultdict(dict) 设置简单的数据类时遇到问题。

如果我告诉工厂使用“dict”,如下所示,实例化将失败并出现typerror collection.defaultdict对象不可调用

from collections import defaultdict
from dataclasses import dataclass, field

@dataclass
class ResultSet:
    changed: bool = False
    mqttdata:  defaultdict(dict) = field(default_factory=defaultdict(dict)) # does not work!
Run Code Online (Sandbox Code Playgroud)

它确实使用field(default_factory=defaultdict)工作,但是当我的代码遇到丢失的键时,它会失败 - 大概是因为没有为 dict 设置 defaultdict。

如何在数据类中正确设置新的defaultdict(dict)?

rv.*_*tch 22

您的代码以及dataclasses当前的使用方式存在一些问题:

  • 注解中的类型泛型一般需要通过方括号来指定[],所以default[dict]而不是defaultdict(dict)例如。

  • default_factory的参数必须dataclasses.field()是无参数可调用,它返回一个设置了默认值的新对象。例如,假设您有一个Inner指定所有字段默认值的嵌套数据类,则您可以在每次实例化主数据类时创建default_factory=Inner一个新对象。Inner

    请注意,该参数主要对可变类型(例如、和)default_factory有用,因此同一对象不会在数据类实例之间共享(并且可能会发生变化)。setlistdict


把它们放在一起,下面是为类型字段设置默认值的工作代码defaultdict[dict]

from collections import defaultdict
from dataclasses import dataclass, field


@dataclass
class ResultSet:
    changed: bool = False
    mqttdata: defaultdict[dict] = field(default_factory=lambda: defaultdict(dict))  # works!


print(ResultSet())
Run Code Online (Sandbox Code Playgroud)

在早于 3.9 的 Python 版本(即PEP 585引入时)中,您需要在顶部添加以下导入,以便对任何类型注释进行惰性求值

from __future__ import annotations
Run Code Online (Sandbox Code Playgroud)