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
相关产品推荐
相关产品推荐

