You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python解析JSON中的嵌套字典:加载含嵌套结构的JSON文件

解析带嵌套字典的JSON结构(使用json.loads的object_hook)

你已经在用json.loads的object_hook参数来处理JSON到自定义对象的转换了,这路子是对的!针对你JSON里嵌套的stats字典,关键是让decode_character函数能区分不同层级的对象,下面分两种常见需求给你具体实现方案:

场景1:仅把顶层怪物转成自定义类,stats保留字典

如果你的需求只是把顶层的monster对象转为自定义类实例,嵌套的stats保持普通Python字典就行,那可以这么写:

首先定义你的Monster类,字段名按Python的下划线风格来(和JSON的驼峰命名对应):

import json

class Monster:
    def __init__(self, name, level, hp_total, attacks, stats):
        self.name = name
        self.level = level
        self.hp_total = hp_total
        self.attacks = attacks
        self.stats = stats  # 直接接收嵌套的字典

然后编写decode_character函数,通过__class__字段识别顶层怪物对象,其他对象(比如stats)直接返回原字典:

def decode_character(obj):
    # 检查当前对象是不是我们要转换的monster
    if obj.get('__class__') == 'monster':
        return Monster(
            name=obj['name'],
            level=obj['level'],
            hp_total=obj['hpTotal'],  # 映射JSON的驼峰键到Python的下划线属性
            attacks=obj['attacks'],
            stats=obj['stats']  # 嵌套字典直接传递,不用额外处理
        )
    # 不是monster的对象(比如stats),原样返回
    return obj

调用你的loadCharacters函数后,返回的就是Monster实例,访问stats里的属性直接用字典索引就行,比如monster.stats['AC']。

场景2:把嵌套的stats也转成自定义类

如果你想让stats也变成面向对象的类实例(比如Stats类),那只需要在decode_character里递归处理嵌套结构就行:

先定义Stats类:

class Stats:
    def __init__(self, ac, str_, dex, con, int_, wis, cha):
        self.ac = ac
        self.str = str_  # 避免和Python内置的str关键字冲突,用str_代替
        self.dex = dex
        self.con = con
        self.int = int_
        self.wis = wis
        self.cha = cha

然后修改decode_character,增加对stats对象的判断(可以通过字段集合来识别,或者给stats也加个__class__标记):

def decode_character(obj):
    # 先处理顶层的monster
    if obj.get('__class__') == 'monster':
        return Monster(
            name=obj['name'],
            level=obj['level'],
            hp_total=obj['hpTotal'],
            attacks=obj['attacks'],
            stats=decode_character(obj['stats'])  # 递归调用,处理嵌套的stats
        )
    # 判断是不是stats对象(检查是否包含所有属性键)
    elif all(key in obj for key in ['AC', 'STR', 'DEX', 'CON', 'INT', 'WIS', 'CHA']):
        return Stats(
            ac=obj['AC'],
            str_=obj['STR'],
            dex=obj['DEX'],
            con=obj['CON'],
            int_=obj['INT'],
            wis=obj['WIS'],
            cha=obj['CHA']
        )
    # 其他未知对象,原样返回
    return obj

这样处理后,monster.stats就是Stats类的实例,你可以用monster.stats.ac这种更直观的方式访问属性。

重要提示

  • object_hook是递归生效的:JSON里每一个用{}包裹的结构,都会被传入decode_character函数,所以一定要做好类型判断,别把所有字典都转成同一个类。
  • 字段映射要注意:JSON里的驼峰命名(比如hpTotal)在Python里建议转成下划线风格(hp_total),符合PEP8规范。
  • 如果以后有更多嵌套类型,只需要在decode_character里加对应的判断逻辑就行。

最后测试一下你的代码,确保能正常工作:

def loadCharacters(fileLoc):
    with open(fileLoc) as character_data:
        data = character_data.read()
        characterDictionary = json.loads(data, object_hook=decode_character)
        return characterDictionary

# 假设你的JSON文件叫monster.json
mugger = loadCharacters('monster.json')
print(mugger.name)  # 输出: Mugger
print(mugger.stats.ac)  # 场景2下输出12;场景1用mugger.stats['AC']

内容的提问来源于stack exchange,提问作者donlonc

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:24:20