【问题标题】:Looping over a dataclass and fill values循环遍历数据类并填充值
【发布时间】:2021-09-22 14:41:44
【问题描述】:

我想用值填充数据类(不是在初始化时)。我试过了:

from random import randint
from dataclasses import dataclass

@dataclass
class VData:
    var_a: list = None
    var_b: list = None
    var_c: list = None

X = VData

for var in VData.__dataclass_fields__:
    l = [randint(0, 10), randint(0,10)]
    X.__setattr__(X, var, l) 

但得到错误:can't apply this __setattr__ to type object。如何正确循环变量?

【问题讨论】:

  • 您似乎正在尝试将数据类字段用作类变量。如果是这样,我会将它们注释为 ClassVar[list]
  • 也使用fields 而不是x.__dataclass_fields__,这是未记录的,将来可能会在某个地方中断
  • 你想用值或类的实例填充类本身吗?
  • 我想用不同的开始列表(一组坐标)创建这个类的多个实例。

标签: python-3.x python-dataclasses


【解决方案1】:

使用fields。作为一般规则,请避免使用像 __setattr__ 这样的魔法方法。

from random import randint
from dataclasses import dataclass, fields


@dataclass
class VData:
    var_a: list = None
    var_b: list = None
    var_c: list = None

X = VData()
xfilds = fields(VData)

for var in xfilds:
    l = [randint(0, 10), randint(0,10)]
    setattr(X, var.name, l)

# VData(var_a=[10, 2], var_b=[8, 9], var_c=[0, 6])

注意:xfilds 被缓存,asdict 没有。

【讨论】:

    【解决方案2】:

    使用 asdictsetattr 而不是它们的 dunder 等价物。

    from random import randint
    from dataclasses import dataclass, asdict
    
    @dataclass
    class VData:
        var_a: list = None
        var_b: list = None
        var_c: list = None
    # you were missing a () which instantiates the object
    inst = VData()
    
    # Here, asdict gives you the dictionary form of a dataclass instance
    # fields would work too as @rv.ketch pointed out
    # if you don't have a need for the values of the dict
    for var in asdict(inst):
        l = [randint(0, 10), randint(0,10)]
        setattr(inst, var, l)
    
    print(inst)
    

    【讨论】:

      猜你喜欢
      • 2017-02-16
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多