Consider this json file named h.json
I want to convert this into a python dataclass.
{
"acc1":{
"email":"acc1@example.com",
"password":"acc1",
"name":"ACC1",
"salary":1
},
"acc2":{
"email":"acc2@example.com",
"password":"acc2",
"name":"ACC2",
"salary":2
}
}
I could use an alternative constructor for getting each account, for example:
import json
from dataclasses import dataclass
@dataclass
class Account(object):
email:str
password:str
name:str
salary:int
@classmethod
def from_json(cls, json_key):
file = json.load(open("h.json"))
return cls(**file[json_key])
but this is limited to what arguments (email, name, etc.) were defined in the dataclass.
What if I were to modify the json to include another thing, say age?
The script would end up returning a TypeError
, specifically TypeError: __init__() got an unexpected keyword argument 'age'
.
Is there a way to dynamically adjust the class attributes based on the keys of the dict (json object), so that I don't have to add attributes each time I add a new key to the json?
This way you lose some dataclass
features.
optional
or notHowever, you are more familiar with your project and decide accordingly
There must be many methods, but this is one of them:
@dataclass
class Account(object):
email: str
password: str
name: str
salary: int
@classmethod
def from_json(cls, json_key):
file = json.load(open("1.txt"))
keys = [f.name for f in fields(cls)]
# or: keys = cls.__dataclass_fields__.keys()
json_data = file[json_key]
normal_json_data = {key: json_data[key] for key in json_data if key in keys}
anormal_json_data = {key: json_data[key] for key in json_data if key not in keys}
tmp = cls(**normal_json_data)
for anormal_key in anormal_json_data:
setattr(tmp,anormal_key,anormal_json_data[anormal_key])
return tmp
test = Account.from_json("acc1")
print(test.age)