Home > Software design >  Looping over a dataclass and fill values
Looping over a dataclass and fill values

Time:09-22

I want to fill a dataclass with values (not on initialization). I tried:

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) 

but get the error: can't apply this __setattr__ to type object. How do I correctly loop over the variables?

CodePudding user response:

Use asdict and setattr rather than their dunder equivalents.

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)

CodePudding user response:

Use fields. Avoid magic methods like __setattr__ as a general rule.

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])

Note: xfilds is cached, asdict is not.

  • Related