因此,我正在尝试编写一个自定义编码器,以处理不同的jar
值:
ooxml-lib
但是,它似乎没有处理numpy
或class NumpyEncoder(DjangoJSONEncoder):
def default(self, obj):
if isinstance(obj, np.integer):
return int(obj)
elif isinstance(obj, np.floating):
return float(obj)
elif isinstance(obj, np.ndarray):
return obj.tolist()
if np.isnan(obj) or np.isinf(obj):
return None
else:
return super().default(obj)
对象:
np.NaN
我也尝试过使用np.inf
,但这也不起作用。
我想要将obj = {'test': np.NaN, 'test2': np.inf}
json.dumps(obj, cls=LazyNumpyEncoder)
Out[5]: '{"test": NaN, "test2": Infinity}'
和Infinite(包括负的无限值)转换为空值。
有人知道我哪里出问题了吗?
答案 0 :(得分:1)
这里的原因是$userData = $request->validate([
'email' => 'required|string|email|max:255|unique:users',
'number_of_whatever' => 'nullable'
]);
方法只能用于使 new 类型可序列化。它不能用于覆盖default
中已经定义的类型的序列化。 json
的文档字符串说的是(强调我的):
要将其扩展为识别其他对象,请使用其他方法子类化并实现
JSONEncoder
方法,并在可能的情况下为.default()
返回可序列化的对象,否则应调用超类实现(引发o
)。
如果查看源代码,您会注意到在所有其他序列化尝试均失败之后,将调用TypeError
。因此,OP帖子中的代码不会被调用。根据以上引用,default
实现了DjangoJSONEncoder
以使其了解日期/时间,十进制类型和UUID。
关于如何解决此问题的方法-好吧,我不会理会子类化,而是递归地处理dict(请注意循环!),并在将dict传递到{{之前,用default
替换NaN和Infs。 1}}。也可以使用None
来确保在调用转储之前捕获了所有NaN。
另一个选择-子类json.dumps
/ json.dumps(..., allow_nan=False)
,覆盖JSONEncoder
,插入上述算法,并将其余工作传递给父类。
答案 1 :(得分:1)
所以@Vovanrock很好地解释了它,但我将发布解决该问题的方法。在通过dumps
运行字典之前,我只是将inf
和nan
对象转换为字符串:
def _convert_numpy_objects(self, dict_to_convert : Dict) -> Dict:
new = {}
for k, v in dict_to_convert.items():
if isinstance(v, dict):
new[k] = self._convert_numpy_objects(v)
else:
if isinstance(v, float) and (np.isnan(v) or np.isinf(v)):
new[k] = str(v)
else:
new[k] = v
return new