使用自定义python 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__._

下面是一个将浮点值转换为字符串的简单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__.__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,但如果是这样,为什么第一个测试会通过?@gidim
json.dumps(float('Inf'))
默认情况下返回一个字符串“无穷大”。我不确定这是为什么,但我在ipython进行了测试。我还通过插入一个从未命中的断点来测试您的类和函数。@gidim看起来像是根据json规范,
Infinity
只能是一个值,它只能位于对象或数组内部:我认为规范根本不允许无限,这就是我试图将其转换为字符串的原因。第一个测试确实击中了NestedEncoder,第二个没有。即使支持dic,也应调用其值否?@jordanm如何覆盖
encode
。。?