首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何将json文件转换为python类?

如何将json文件转换为python类?
EN

Stack Overflow用户
提问于 2021-10-29 18:47:39
回答 3查看 5.2K关注 0票数 3

考虑这个名为h.json的json文件,我想将它转换为python。

代码语言:javascript
运行
复制
{
    "acc1":{
        "email":"acc1@example.com",
        "password":"acc1",
        "name":"ACC1",
        "salary":1
    },
    "acc2":{
        "email":"acc2@example.com",
        "password":"acc2",
        "name":"ACC2",
        "salary":2
    }

}

我可以使用另一个构造函数来获取每个帐户,例如:

代码语言:javascript
运行
复制
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])

但这仅限于哪些论点(电子邮件、姓名等)。都是在数据集中定义的。

如果我修改json以包括另一件事,比如年龄,该怎么办?脚本将返回一个TypeError,特别是TypeError: __init__() got an unexpected keyword argument 'age'

是否有一种方法可以根据dict (json对象)的键动态调整类属性,这样我就不必每次向json添加新键时都要添加属性了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-10-29 19:11:14

这样,您就失去了一些dataclass特性。

  • 例如确定它是否是optional
  • 例如自动完成功能。

然而,您更熟悉您的项目并做出相应的决定。

必须有许多方法,但这是其中之一:

代码语言:javascript
运行
复制
@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)
票数 3
EN

Stack Overflow用户

发布于 2021-10-29 22:15:58

由于您的数据听起来可能是动态的,并且您希望可以在JSON对象中添加更多字段而不反映模型中的相同更改,所以我还建议检查typing.TypedDict而不是dataclass

下面是TypedDict的一个示例,它应该在Python中工作。由于TypedDict是在3.8中介绍,所以我从typing_extensions导入了它,所以它与3.7代码兼容。

代码语言:javascript
运行
复制
from __future__ import annotations

import json
from io import StringIO
from typing_extensions import TypedDict


class Account(TypedDict):
    email: str
    password: str
    name: str
    salary: int


json_data = StringIO("""{
    "acc1":{
        "email":"acc1@example.com",
        "password":"acc1",
        "name":"ACC1",
        "salary":1
    },
    "acc2":{
        "email":"acc2@example.com",
        "password":"acc2",
        "name":"ACC2",
        "salary":2,
        "someRandomKey": "string"
    }
}
""")

data = json.load(json_data)
name_to_account: dict[str, Account] = data

acct = name_to_account['acc2']

# Your IDE should be able to offer auto-complete suggestions within the
# brackets, when you start typing or press 'Ctrl + Space' for example.
print(acct['someRandomKey'])

如果您打算使用dataclass来建模您的数据,我建议您签出一个JSON序列化库,比如数据处理-向导 (免责声明:我是创建者),它应该处理JSON数据中的无关字段,如果您发现数据变得更加复杂,也应该使用嵌套的数据处理模型。

它还有一个方便的工具,您可以使用它从JSON数据生成数据集模式,例如,如果您想在JSON文件中添加新字段时更新您的模型类,这是非常有用的。

票数 6
EN

Stack Overflow用户

发布于 2021-10-29 18:53:58

对于一个平面(而不是嵌套的数据集),下面的代码完成了这项工作。

如果您需要处理嵌套的数据类型,则应该使用类似于dacite的框架。

注释1 --从json文件加载数据不应该是类逻辑的一部分。

如果您的json可以包含任何内容-您不能将它映射到一个数据集,那么您应该使用一个

代码语言:javascript
运行
复制
from dataclasses import dataclass
from typing import List

data = {
    "acc1":{
        "email":"acc1@example.com",
        "password":"acc1",
        "name":"ACC1",
        "salary":1
    },
    "acc2":{
        "email":"acc2@example.com",
        "password":"acc2",
        "name":"ACC2",
        "salary":2
    }

}



@dataclass
class Account:
    email:str
    password:str
    name:str
    salary:int

accounts: List[Account] = [Account(**x) for x in data.values()]
print(accounts)

输出

代码语言:javascript
运行
复制
[Account(email='acc1@example.com', password='acc1', name='ACC1', salary=1), Account(email='acc2@example.com', password='acc2', name='ACC2', salary=2)]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69773539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档