Python JSON serialize a Decimal object

后端 未结 17 1170
星月不相逢
星月不相逢 2020-11-22 08:27

I have a Decimal(\'3.9\') as part of an object, and wish to encode this to a JSON string which should look like {\'x\': 3.9}. I don\'t care about p

17条回答
  •  渐次进展
    2020-11-22 09:02

    This is what I have, extracted from our class

    class CommonJSONEncoder(json.JSONEncoder):
    
        """
        Common JSON Encoder
        json.dumps(myString, cls=CommonJSONEncoder)
        """
    
        def default(self, obj):
    
            if isinstance(obj, decimal.Decimal):
                return {'type{decimal}': str(obj)}
    
    class CommonJSONDecoder(json.JSONDecoder):
    
        """
        Common JSON Encoder
        json.loads(myString, cls=CommonJSONEncoder)
        """
    
        @classmethod
        def object_hook(cls, obj):
            for key in obj:
                if isinstance(key, six.string_types):
                    if 'type{decimal}' == key:
                        try:
                            return decimal.Decimal(obj[key])
                        except:
                            pass
    
        def __init__(self, **kwargs):
            kwargs['object_hook'] = self.object_hook
            super(CommonJSONDecoder, self).__init__(**kwargs)
    

    Which passes unittest:

    def test_encode_and_decode_decimal(self):
        obj = Decimal('1.11')
        result = json.dumps(obj, cls=CommonJSONEncoder)
        self.assertTrue('type{decimal}' in result)
        new_obj = json.loads(result, cls=CommonJSONDecoder)
        self.assertEqual(new_obj, obj)
    
        obj = {'test': Decimal('1.11')}
        result = json.dumps(obj, cls=CommonJSONEncoder)
        self.assertTrue('type{decimal}' in result)
        new_obj = json.loads(result, cls=CommonJSONDecoder)
        self.assertEqual(new_obj, obj)
    
        obj = {'test': {'abc': Decimal('1.11')}}
        result = json.dumps(obj, cls=CommonJSONEncoder)
        self.assertTrue('type{decimal}' in result)
        new_obj = json.loads(result, cls=CommonJSONDecoder)
        self.assertEqual(new_obj, obj)
    

提交回复
热议问题