python - 如何递归地jsonize python对象

标签 python json dictionary serialization

我有以下对象:

class Heading:

    def __init__(self, text):
        self._text = text
        self._subheadings = []

    def add_subheading(self, sub):
        self._subheadings.append(sub)

我的 h1 类型为 Heading 例如包含以下结构:

enter image description here

所以这个 h1 包含(您看不到全部)4 个 h2。 h2 可能包含也可能不包含 h3s 等等。递归地,每个对象都是 Heading 类型,并且是 _subheadings 的一部分。

我现在想把这个结构序列化成一个json字符串。实现这一目标最顺利的方法是什么?否则我会构建这样的东西(显然它还没有完成,现在它只是遍历所有标题):

def jsonize_headings(self):

    # main object
    headings = {}

    # h1 heading
    headings["h1_heading"] = self.h1_heading.text

    # h2 headings
    for h2 in self.h1_heading.subheadings:
        h2_dict = dict()
        h2_dict["h2_heading"] = h2.text

        # h3 headings
        for h3 in h2.subheadings:
            h3_dict = dict()
            h3_dict["h3_heading"] = h3.text

            # h4 headings
            for h4 in h3.subheadings:
                h4_dict = dict()
                h4_dict["h4_heading"] = h4.text

                # h5 headings
                for h5 in h4.subheadings:
                    h5_dict = dict()
                    h5_dict["h5_heading"] = h5.text

                    # h6 headings
                    for h6 in h5.subheadings:
                        h6_dict = dict()
                        h6_dict["h6_heading"] = h6.text

最终结果:

class Heading:

    def __init__(self, text):
        self._text = text
        self._subheadings = []

    def add_subheading(self, sub):
        self._subheadings.append(sub)

    @property
    def text(self):
        return self._text

    @property
    def subheadings(self):
        return self._subheadings

    @classmethod
    def to_dict(cls, _obj):

        def _to_dict(d, c=1):
            e = dict()
            e[f"h{c}_heading"] = d.text
            if d.subheadings:
                e[f"h{c+1}_headings"] = [_to_dict(sub, c+1) for sub in d.subheadings]
            return e

        return _to_dict((_obj))

我上面显示的大文章的输出是:

{
    "h1_heading": "Staatskrise in Ägypten 2013/2014 (Kabinett Beblawi)",
    "h2_headings": [
        {
            "h2_heading": "Vorgeschichte",
            "h3_headings": [
                {
                    "h3_heading": "Installation einer Übergangsregierung durch das Militär"
                }
            ]
        },
        {
            "h2_heading": "Militärgestützte Übergangsregierung – Kabinett Beblawi",
            "h3_headings": [
                {
                    "h3_heading": "Propaganda gegen Muslimbrüder und Repressalien gegen Medien"
                },
                {
                    "h3_heading": "Medienkampagne und Restriktionen gegen Flüchtlinge"
                },
                {
                    "h3_heading": "Massentötung von Mursi-Unterstützern im Protestcamp am Rābiʿa-al-ʿAdawiyya-Platz (27. Juli)"
                },
                {
                    "h3_heading": "Blutbad durch Räumung der Protestlager am Rābiʿa-al-ʿAdawiyya- und Al-Nahda-Platz (14. August)"
                },
                {
                    "h3_heading": "Ausnahmezustand",
                    "h4_headings": [
                        {
                            "h4_heading": "Konditionen zu Ausnahmezustand und Ausgangssperre"
                        },
                        {
                            "h4_heading": "Verfolgung von Muslimbrüdern und Verbot ihrer Organisationen",
                            "h5_headings": [
                                {
                                    "h5_heading": "Prozess gegen Führungsriege der Muslimbrüder"
                                },
                                {
                                    "h5_heading": "Prozess gegen Mursi",
                                    "h6_headings": [
                                        {
                                            "h6_heading": "Prozess- und Haftbedingungen"
                                        },
                                        {
                                            "h6_heading": "Haltung Mursis und der Muslimbruderschaft"
                                        },
                                        {
                                            "h6_heading": "Ablauf"
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "h4_heading": "Übergriffe auf Christen (Mitte August)",
                            "h5_headings": [
                                {
                                    "h5_heading": "Frühe Meldungen"
                                },
                                {
                                    "h5_heading": "Opfer und Schäden"
                                },
                                {
                                    "h5_heading": "Reaktionen und Wertungen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "R4bia-Kampagne"
                        },
                        {
                            "h4_heading": "Fortsetzung der Gewalt und Blutbad bei der Al-Fetah-Moschee am Ramses-Platz (16. August)"
                        },
                        {
                            "h4_heading": "Massentod von Untersuchungshäftlingen (18. August)",
                            "h5_headings": [
                                {
                                    "h5_heading": "Darstellung des Militärregimes"
                                },
                                {
                                    "h5_heading": "Darstellung der Muslimbruderschaft"
                                },
                                {
                                    "h5_heading": "Strafverfolgung"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Ausreise el-Baradeis (18. August)"
                        },
                        {
                            "h4_heading": "Mubarak-Prozess und Sisis mögliche Präsidentschaftskandidatur",
                            "h5_headings": [
                                {
                                    "h5_heading": "Prozess gegen Mubarak und seine Haftentlassung"
                                },
                                {
                                    "h5_heading": "Frage der Restauration von Mubarak-Strukturen"
                                },
                                {
                                    "h5_heading": "Frage einer Präsidentschaftskandidatur Sisis"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Militäroperation auf dem Sinai"
                        },
                        {
                            "h4_heading": "Aufkommende Konflikte zwischen liberalen Oppositionellen und Staatsapparat",
                            "h5_headings": [
                                {
                                    "h5_heading": "Mohamed el-Baradei"
                                },
                                {
                                    "h5_heading": "Wael Ghonim, Amr Hamzawy, Israa Abdel Fatta, Ahmed Maher und Andere"
                                },
                                {
                                    "h5_heading": "Ahmed Abu Daraa und Haitham Mohamadeen"
                                },
                                {
                                    "h5_heading": "Bassem Youssef"
                                },
                                {
                                    "h5_heading": "Meinungen und Wertungen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Proteste an Universitäten",
                            "h5_headings": [
                                {
                                    "h5_heading": "Ablauf"
                                },
                                {
                                    "h5_heading": "Opfer"
                                },
                                {
                                    "h5_heading": "Festnahmen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "40. Jahrestag des Jom-Kippur-Krieges (6. Oktober)"
                        },
                        {
                            "h4_heading": "Vorwurf der Straffreiheit bei Verbrechen gegen Mursi-Anhänger"
                        },
                        {
                            "h4_heading": "Einfrieren von Teilen der US-Militärhilfe und Ägyptenbesuch Kerrys",
                            "h5_headings": [
                                {
                                    "h5_heading": "Einfrieren von Teilen der US-Militärhilfe (9. Oktober)",
                                    "h6_headings": [
                                        {
                                            "h6_heading": "Umfang und Form der Einschränkungen"
                                        },
                                        {
                                            "h6_heading": "Reaktionen und Bedeutung"
                                        }
                                    ]
                                },
                                {
                                    "h5_heading": "Ägypten-Besuch bei Nahost-Reise John Kerrys (3. November)"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Gesetzliche Maßnahmen und Initiativen",
                            "h5_headings": [
                                {
                                    "h5_heading": "Ausarbeitung einer neuen Verfassung",
                                    "h6_headings": [
                                        {
                                            "h6_heading": "Verfassung von 2012"
                                        },
                                        {
                                            "h6_heading": "Erarbeitung des neuen Entwurfes"
                                        },
                                        {
                                            "h6_heading": "Fachliche Einschätzungen"
                                        }
                                    ]
                                },
                                {
                                    "h5_heading": "„Anti-Terror-Gesetz“"
                                },
                                {
                                    "h5_heading": "Abschaffung des Oberhauses (Schura-Rat)"
                                },
                                {
                                    "h5_heading": "Demonstrationsgesetz"
                                },
                                {
                                    "h5_heading": "Staatliche Kontrolle über Moscheen und Prediger"
                                },
                                {
                                    "h5_heading": "Zeitplan für Präsidentschafts- und Parlamentswahlen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Neue Wohltätigkeitsorganisation von Muslimbrüdern"
                        },
                        {
                            "h4_heading": "Weitere Gewalttaten und Auseinandersetzungen",
                            "h5_headings": [
                                {
                                    "h5_heading": "August"
                                },
                                {
                                    "h5_heading": "September"
                                },
                                {
                                    "h5_heading": "Oktober"
                                },
                                {
                                    "h5_heading": "November"
                                }
                            ]
                        }
                    ]
                },
                {
                    "h3_heading": "Entwicklung nach Ende des Ausnahmezustandes",
                    "h4_headings": [
                        {
                            "h4_heading": "Haftbedingungen und Foltervorwürfe"
                        },
                        {
                            "h4_heading": "Staatskampagne gegen ausländische Medien",
                            "h5_headings": [
                                {
                                    "h5_heading": "Prozesse gegen Al-Jazeera-Journalisten"
                                },
                                {
                                    "h5_heading": "Reaktionen und Wertungen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Verfassungsreferendum",
                            "h5_headings": [
                                {
                                    "h5_heading": "Vorfeld und Ablauf der Wahl"
                                },
                                {
                                    "h5_heading": "Inhalt der neuen Verfassung"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Gewalt am dritten Jahrestag des Aufstands gegen Mubarak (25. Januar 2014)",
                            "h5_headings": [
                                {
                                    "h5_heading": "Todesopfer und Verletzte"
                                },
                                {
                                    "h5_heading": "Ablauf"
                                },
                                {
                                    "h5_heading": "Reaktionen und Wertungen",
                                    "h6_headings": [
                                        {
                                            "h6_heading": "National"
                                        },
                                        {
                                            "h6_heading": "International"
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "h4_heading": "Rücktritt des Kabinetts Beblawi",
                            "h5_headings": [
                                {
                                    "h5_heading": "Reaktionen und Wertungen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Bildung einer neuen Übergangsregierung",
                            "h5_headings": [
                                {
                                    "h5_heading": "Vereidigung und Zusammensetzung"
                                },
                                {
                                    "h5_heading": "Reaktionen"
                                }
                            ]
                        },
                        {
                            "h4_heading": "Unions-Fraktionschef Kauder in Kairo",
                            "h5_headings": [
                                {
                                    "h5_heading": "Appell für europäische Zusammenarbeit mit ägyptischem Militärregime"
                                },
                                {
                                    "h5_heading": "Reaktionen und Wertungen"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "h2_heading": "Militärgestützte Übergangsregierung – Kabinett Mahlab"
        },
        {
            "h2_heading": "Verweise",
            "h3_headings": [
                {
                    "h3_heading": "Weblinks"
                },
                {
                    "h3_heading": "Einzelnachweise"
                }
            ]
        }
    ]
}

最佳答案

您可以通过 itertools.count 使用递归:

import itertools
class Heading:
   def __init__(self, text):
     self._text = text
     self._subheadings = []
   def add_subheading(self, sub):
     self._subheadings.append(sub)
   @classmethod
   def to_dict(cls, _obj):
     c = itertools.count(1)
     def _to_dict(d):
        return {f'h{next(c)}_heading':d._text, 'children':list(map(_to_dict, d._subheadings))}
     return _to_dict(_obj)

现在:

import json
h, c1, c2 = Heading('test_header1'), Heading('test_sub_header1'), Heading('test_sub_header2')
c1.add_subheading(c2)
h.add_subheading(c1)
print(json.dumps(Heading.to_dict(h), indent=4))

输出:

{
    "h1_heading": "test_header1",
    "children": [
    {
        "h2_heading": "test_sub_header1",
        "children": [
            {
                "h3_heading": "test_sub_header2",
                "children": []
            }
        ]
      }
   ]  
}

这是一个简化的示例,但是可以轻松更新递归过程以支持自定义键名等。

关于python - 如何递归地jsonize python对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58355206/

相关文章:

python - 如何计算两个 Pandas 时间轴向量之间的 PIL 逊相关性

python - 使用python分割json中的字符串

python - 下载过去一周特定游戏的 50 个 twitch.tv 剪辑

python - 如何使用 Python 搜索字典值是否包含特定字符串

python - 用未知键初始化一个大字典?还有比这更好的方法吗?

python - 当其中一个元素是 Python 字典时,向 MySQL 表中插入一行

python - 从字符串中取出空格,并用 “+”替换它们

python - 使用 requests 函数下载页面时遇到问题 - 返回 410 html 错误代码,但在浏览器中有效

Python - PyGame - 学习向量/动画

python - 我需要取消嵌套 JSON 数组元素并确保与 'ID' 列的正确映射