numpy recarray嵌套实现求助:JSON加载后属性访问失败
解决嵌套numpy.recarray属性访问失效问题
问题场景
你希望将多个JSON文件加载为嵌套的numpy.recarray结构,实现parms.logic.myVarA这类简化的属性访问,但实际测试中发现:子JSON加载生成的recarray,被加入全局recarray后会自动转为numpy.ndarray类型,导致无法通过点语法访问属性。
问题根源
numpy的recarray本质是结构化数组的子类,它的字段仅支持存储基础数据类型(如int、float)或固定维度的普通数组。当你尝试把一个recarray作为另一个recarray的字段值时,numpy会自动将嵌套的recarray转换为普通ndarray——因为结构化数组不支持嵌套的recarray类型,只能把嵌套结构当作普通数组处理,自然就丢失了属性访问的特性。
解决方案
方案1:自定义类封装(推荐,灵活可控)
不用强行依赖recarray,写一个极简的类将JSON字典转为可属性访问的对象,嵌套结构也能完美保留:
import json class AttrDict: def __init__(self, data): for key, value in data.items(): # 递归处理嵌套字典 setattr(self, key, AttrDict(value) if isinstance(value, dict) else value) def load_json(path): with open(path, 'r', encoding='utf-8') as f: return json.load(f) # 构建全局嵌套结构 parms = AttrDict({ 'logic': AttrDict(load_json('logic.json')), 'tool': AttrDict(load_json('tool.json')) }) # 测试属性访问 print(parms.logic.myVarA)
这个方案完全满足parms.logic.myVarA的访问需求,且不受numpy数据类型限制,比recarray更灵活。
方案2:保留numpy特性的结构化数组(不推荐,访问不便)
如果必须用numpy结构,可以定义嵌套的dtype,但无法直接用点语法访问嵌套属性,只能通过键索引:
import numpy as np import json # 定义嵌套数据类型 logic_dtype = [('myVarA', 'float64'), ('myVarB', 'int32')] tool_dtype = [('myVarX', 'U10'), ('myVarY', 'float64')] parms_dtype = [('logic', logic_dtype), ('tool', tool_dtype)] # 加载JSON数据 logic_data = json.load(open('logic.json', 'r')) tool_data = json.load(open('tool.json', 'r')) # 构造recarray parms = np.recarray(1, dtype=parms_dtype)[0] # 手动填充数据 for k, v in logic_data.items(): parms.logic[k] = v for k, v in tool_data.items(): parms.tool[k] = v # 访问方式(需用键索引,无法点访问) print(parms.logic['myVarA'])
方案3:使用第三方库(快速实现)
用现成的attrdict库直接实现字典到可属性访问对象的转换,支持嵌套:
- 先安装库:
pip install attrdict
- 代码实现:
from attrdict import AttrDict import json def load_json(path): with open(path, 'r') as f: return AttrDict(json.load(f)) parms = AttrDict({ 'logic': load_json('logic.json'), 'tool': load_json('tool.json') }) print(parms.logic.myVarA)
内容的提问来源于stack exchange,提问作者Freelax FPV
相关产品推荐
相关产品推荐

