【问题标题】:dataclasses: how to ignore default values using asdict()?数据类:如何使用 asdict() 忽略默认值?
【发布时间】:2022-11-03 01:25:38
【问题描述】:

我想在调用 asdict() 后忽略默认值

@dataclass
class A:
    a: str
    b: bool = True

所以如果我打电话

a = A("1")
result = asdict(a, ignore_default=True) 
assert {"a": "1"} == result  # the "b": True should be deleted

【问题讨论】:

  • 这是不可能的。 a = A(1)b = A(1, True) 没有区别
  • 我想 asdict 返回一个没有默认值的字典
  • 对于不可变类型,这并不太难,但否则很难区分b = []; a = A(b)a = A([])(在这两种情况下,成员都是[],但在第一种情况下,它是“重要的”,因为它与b 外面的对象)。如果您不关心这种情况,那么您可以从上面的问题中调整一些代码。
  • 你需要区分上面提到的A(1)A(1, True)的情况吗?如果是,您可以连接到A__init__ 函数来记录类型。否则,如果您可以修改数据类类型创建,则只需使用exclude 元数据,否则修改asdict 函数,但如果默认值类似于default_factory([]),则会出现上述问题。

标签: python python-dataclasses


【解决方案1】:

dataclasses 模块似乎不支持检测asdict 中的默认值,但dataclass-wizard 库支持。

例子:

from dataclasses import dataclass

from dataclass_wizard import asdict


@dataclass
class A:
    a: str
    b: bool = True


a = A("1")
result = asdict(a, skip_defaults=True)
assert {"a": "1"} == result  # the "b": True should be deleted

【讨论】:

    【解决方案2】:

    您可以将工厂函数传递给asdict(),它使您可以控制要从传递的对象返回的内容,该对象基本上是键值对元组的列表。

    dataclass 将其字段存储为__dataclass_fields__ 属性,该属性是Field 的一个实例。如果属性将其default 设置为_MISSING_TYPE 的实例,则意味着它没有默认值。所以选择它:

    from dataclasses import dataclass, asdict, _MISSING_TYPE
    
    
    def factory(obj):
        d = {}
        for k, v in obj:
            field = A.__dataclass_fields__[k]
            if type(field.default) is _MISSING_TYPE:
                d[k] = v
        return d
    
    
    @dataclass
    class A:
        a: str
        b: bool = True
    
    
    a = A("1")
    result = asdict(a, dict_factory=factory)
    print(result)
    

    输出:

    {'a': '1'}
    

    【讨论】:

      猜你喜欢
      • 2019-11-12
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2020-04-06
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多