从 Json 字符串创建 Python 对象 [重复]

Posted

技术标签:

【中文标题】从 Json 字符串创建 Python 对象 [重复]【英文标题】:Creating a Python object from a Json string [duplicate] 【发布时间】:2018-08-11 14:18:22 【问题描述】:

到SeismicPortal 的 websocket 连接正在向我发送包含在 JSON 对象中的地震数据,我将其作为多行字符串获取,例如:

                                                                                                                                                                                               
    "action": "create",                                                                                                                                                                         
    "data":                                                                                                                                                                                    
        "geometry":                                                                                                                                                                            
            "coordinates": [                                                                                                                                                                    
                -95.12,                                                                                                                                                                         
                16.52,                                                                                                                                                                          
                -52.0                                                                                                                                                                           
            ],                                                                                                                                                                                  
            "type": "Point"                                                                                                                                                                     
        ,                                                                                                                                                                                      
        "id": "20180303_0000046",                                                                                                                                                               
        "properties":                                                                                                                                                                          
            "auth": "UNM",                                                                                                                                                                      
            "depth": 52.0,                                                                                                                                                                      
            "evtype": "ke",                                                                                                                                                                     
            "flynn_region": "OAXACA, MEXICO",                                                                                                                                                   
            "lastupdate": "2018-03-03T10:26:00.0Z",                                                                                                                                             
            "lat": 16.52,                                                                                                                                                                       
            "lon": -95.12,                                                                                                                                                                      
            "mag": 4.0,                                                                                                                                                                         
            "magtype": "m",                                                                                                                                                                     
            "source_catalog": "EMSC-RTS",                                                                                                                                                       
            "source_id": "652127",                                                                                                                                                              
            "time": "2018-03-03T07:09:05.0Z",                                                                                                                                                   
            "unid": "20180303_0000046"                                                                                                                                                          
        ,                                                                                                                                                                                      
        "type": "Feature"                                                                                                                                                                       
                                                                                                                                                                                               

我想将字符串中的数据转换为 python 对象。

正如您在 JSON 数据中看到的,有很多嵌套。当我定义类及其嵌入性以构建一个结构的对象时,该结构将保存来自 JSON 的所有数据,我在想也许有一些神奇的 Python 函数 jsonStringToObject 可以定制一个类和所有子类都需要保存 JSON 中的所有数据并创建它的实例。

让我们在变量 rawData 中包含原始 JSON 字符串:

rawData = """"action":"create","data":"geometry": "type": "Point","coordinates": [... """

现在我必须这样做:

>>> import json
>>> quake = json.loads(rawData)
>>> quake['data']['properties']['flynn_region']
"OXACA_MEXICO"

但语法中充满了括号和撇号。

我希望我可以像这样访问数据:

>>> import json    
>>> quake = jsonStringToObject(rawData)
>>> quake.data.properties.flynn_region
"OXACA_MEXICO"

【问题讨论】:

JSON 包含列表、字符串、整数和类似的简单对象。它不支持将某些东西定义为您自己的自定义类的实例。因此,由于格式不支持自定义类,JSON 阅读器也不支持它们。您必须拥有自己的函数,例如将 dict 转换为您的类(在将 JSON 解析为 dict 或其他内容之后)。 这个问题好像已经被问过了***.com/questions/6578986/… json.loads 确实给你一个 Python 对象。 @IgSaf 我已经看到了看似“重复”的问题,我已经尝试了使用命名字典的解决方案,其中包含莫名其妙且神奇的“X”。它确实给我一个嵌套的字典结构。然而,Božo Stojković 提供的答案正是我想要的。谢谢你,博兹科! 【参考方案1】:

您可以为此创建自己的课程。使用__getitem____setitem__ 使用点符号从对象的__dict__ 获取和更新值:

import json

class PyJSON(object):
    def __init__(self, d):
        if type(d) is str:
            d = json.loads(d)
        self.convert_json(d)

    def convert_json(self, d):
        self.__dict__ = 
        for key, value in d.items():
            if type(value) is dict:
                value = PyJSON(value)
            self.__dict__[key] = value

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, key):
        return self.__dict__[key]

rawData = """... raw data ..."""

quake = PyJSON(rawData)

按预期工作:

>>> quake.data.properties.flynn_region
'OAXACA, MEXICO'

编辑:添加了to_dict 并覆盖了__repr__,因此更容易在控制台中查看值。将convert_json 重命名为from_dict

import json

class PyJSON(object):
    def __init__(self, d):
        if type(d) is str:
            d = json.loads(d)

        self.from_dict(d)

    def from_dict(self, d):
        self.__dict__ = 
        for key, value in d.items():
            if type(value) is dict:
                value = PyJSON(value)
            self.__dict__[key] = value

    def to_dict(self):
        d = 
        for key, value in self.__dict__.items():
            if type(value) is PyJSON:
                value = value.to_dict()
            d[key] = value
        return d

    def __repr__(self):
        return str(self.to_dict())

    def __setitem__(self, key, value):
        self.__dict__[key] = value

    def __getitem__(self, key):
        return self.__dict__[key]

rawData = """... raw data ..."""

quake = PyJSON(rawData)

之前:

>>> quake.data.geometry
<__main__.PyJSON object at 0xADDRESS>

之后:

>>> quake.data.geometry
'coordinates': [-95.12, 16.52, -52.0], 'type': 'Point'

【讨论】:

convert_json 中的 k/v 是从哪里来的? 我不记得这是怎么发生的了,但从编辑来看,我似乎想让它更具可读性,但忘记更新所有变量名。现在修好了。谢谢!

以上是关于从 Json 字符串创建 Python 对象 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python 从 JSON 文件创建树

从 JSON 创建对象

从JSON格式的字符串创建python列表的最简单方法是啥[重复]

python 对象和json互相转换

Python 和 JSON - 附加到字符串对象

从 python dict 创建 json