Home > other >  Why does indent make a difference for json.dumps
Why does indent make a difference for json.dumps

Time:02-01

What is the difference between having indent set to None and something else? I'm using Python3.
Why does it make not FakeDict([("a": 1, "a": 2)] be evaluated differently?

import os, json, struct, sys, traceback, datetime
class FakeDict(dict):
    def __init__(self, items):
        self._items = items
    def __len__(self):
        return len(self._items)
    def items(self):
        print(self._items)
        return self._items

print(json.dumps(FakeDict([("a", 1), ("a", 2)])))
print("---")
print(json.dumps(FakeDict([("a", 1), ("a", 2)]), indent = 4))
{}
---
[('a', 1), ('a', 2)]
{
    "a": 1,
    "a": 2
}

I was trying to get this class less "Hack-y":

class FakeObject(dict):
    def __init__(self, items):
        if items != []:
            self["something"] = "something"
        self._items = items
    def items(self):
        return self._items

CodePudding user response:

This is because when indent is None, JSON encoder library uses a C function for performance reasons instead of a Python one. Apparently the C function doesn't care about the overridden .items() method like Python:

https://github.com/python/cpython/blob/main/Lib/json/encoder.py#L246

if (_one_shot and c_make_encoder is not None
        and self.indent is None):
    _iterencode = c_make_encoder(
        markers, self.default, _encoder, self.indent,
        self.key_separator, self.item_separator, self.sort_keys,
        self.skipkeys, self.allow_nan)
else:
    _iterencode = _make_iterencode(
        markers, self.default, _encoder, self.indent, floatstr,
        self.key_separator, self.item_separator, self.sort_keys,
        self.skipkeys, _one_shot)
return _iterencode(o, 0)
  •  Tags:  
  • Related