使用自定义python JSON编码器在字典中浮动编码
下面是一个将浮点值转换为字符串的简单JSON编码器:使用自定义python JSON编码器在字典中浮动编码,python,json,Python,Json,下面是一个将浮点值转换为字符串的简单JSON编码器: class NestedEncoder(json.JSONEncoder): ''' A JSON Encoder that converts floats/decimals to strings and allows nested objects ''' def default(self, obj): if isinstance(obj, float) or obj.__class__._
class NestedEncoder(json.JSONEncoder):
'''
A JSON Encoder that converts floats/decimals to strings and allows nested objects
'''
def default(self, obj):
if isinstance(obj, float) or obj.__class__.__name__ == "float32":
return self.floattostr(obj)
elif obj.__class__.__name__ == "type":
return str(obj)
elif hasattr(obj, 'repr_json'):
return obj.repr_json()
else:
return json.JSONEncoder.default(self, obj)
def floattostr(self,o,_inf=float('Inf'), _neginf=-float('-Inf'),nan_str="None"):
if o != o:
text = nan_str
elif o == _inf:
text = 'Infinity'
elif o == _neginf:
text = '-Infinity'
else:
return o.__repr__()
return text
现在有两个测试。第一种方法创建一个无穷大值浮点,并使用自定义编码器对其进行编码。考试通过了
def test_inf():
inf = float('Inf')
as_json = json.dumps(inf,cls=NestedEncoder)
assert as_json == "Infinity"
第二个测试执行相同的操作,但将浮点值放入字典中:
def test_inf_dic():
inf = float('Inf')
as_json = json.dumps({'key':inf},cls=NestedEncoder)
assert as_json == "{'key':'Infinity'}"
输出:
=================================== FAILURES ===================================
_________________________________ test_inf_dic _________________________________
def test_inf_dic():
inf = float('Inf')
as_json = json.dumps({'key':inf},cls=NestedEncoder)
> assert as_json == "{'key':'Infinity'}"
E assert '{"key": Infinity}' == "{'key':'Infinity'}"
E - {"key": Infinity}
E ? ^ ^ ^
E + {'key':'Infinity'}
E ? ^ ^ ^ +
编辑:
自定义编码器只在第一次测试中被调用,而不是在第二次测试中被调用。在测试过程中没有调用自定义函数是正确的。原因在文件中解释: 如果指定,默认值应该是为无法序列化的对象调用的函数。它应该返回对象的JSON可编码版本或引发TypeError。如果未指定,则引发TypeError
由于
float
是一个已经知道如何序列化的对象,因此不调用它。对于float
序列化,您可以重写encode
函数。Python2.7为float('Inf')返回“float”。\uuuuu class\uuu name\uuuuuu
,因此它与第一个条件不匹配。您还试图在测试中将字符串与dict进行比较。@jordanm我修复了该断言。请参阅编码无限的问题。您指出的float('Inf')。\uuuuu class.\uuuu name.\uuuu
问题不相关,因为它是一个或条件Hanks,但如果是这样,为什么第一个测试会通过?@gidimjson.dumps(float('Inf'))
默认情况下返回一个字符串“无穷大”。我不确定这是为什么,但我在ipython进行了测试。我还通过插入一个从未命中的断点来测试您的类和函数。@gidim看起来像是根据json规范,Infinity
只能是一个值,它只能位于对象或数组内部:我认为规范根本不允许无限,这就是我试图将其转换为字符串的原因。第一个测试确实击中了NestedEncoder,第二个没有。即使支持dic,也应调用其值否?@jordanm如何覆盖encode
。。?