JSONEncoder, который сокращает длинные списки - PullRequest
0 голосов
/ 25 февраля 2019

Я хочу вывести несколько больших файлов JSON, печатая только первые несколько элементов каждого списка.Я пытаюсь написать пользовательский кодировщик:

class EllidingEncoder(json.JSONEncoder):
    def encode(self, obj):
        if isinstance(obj, list) and len(obj) > 6:
            return "[{:}, …]".format(", ".join([self.encode(i) for i in obj[:6]]))
        else:
            # The problem....
            return super(EllidingEncoder, self).encode(obj)

Этот тип работ:

$ json.dumps([i for i in range(7)], cls=EllidingEncoder)
> '[0, 1, 2, 3, 4, 5, …]'
$ json.dumps([list([i for i in range(7)] for i in range(7)], cls=EllidingEncoder)
> '[[0, 1, 2, 3, 4, 5, …], [0, 1, 2, 3, 4, 5, …], [0, 1, 2, 3, 4, 5, …], [0, 1, 2, 3, 4, 5, …], [0, 1, 2, 3, 4, 5, …], [0, 1, 2, 3, 4, 5, …], …]'

Но как только список содержится в словаре, все выходит из строя:

$ json.dumps({i:[i for i in range(7)] for i in range(7)}, cls=EllidingEncoder)
> '{"0": [0, 1, 2, 3, 4, 5, 6], "1": [0, 1, 2, 3, 4, 5, 6], "2": [0, 1, 2, 3, 4, 5, 6], "3": [0, 1, 2, 3, 4, 5, 6], "4": [0, 1, 2, 3, 4, 5, 6], "5": [0, 1, 2, 3, 4, 5, 6], "6": [0, 1, 2, 3, 4, 5, 6]}'

Это имеет смысл, поскольку JSONEncoder.encode не может знать, что он должен вызывать EllidingEncoder.encode.

Я начинаю подозревать, что это просто невозможно сделать таким образом.Мой обходной путь должен явно переопределить также для dict's:

class EllidingEncoder(json.JSONEncoder):
    def encode(self, obj):
        if isinstance(obj, list) and len(obj) > 6:
            return "[{:}, …]".format(", ".join([self.encode(i) for i in obj[:6]]))
        elif isinstance(obj, dict):
            return "{{{:}}}".format(", ".join(["{:} : {:}".format(k,self.encode(v)) for k,v in obj.items()]))
        else:
            return super(EllidingEncoder, self).encode(obj)

Любые мысли?

РЕДАКТИРОВАТЬ: списки с более чем 6 элементами также, конечно, должны быть обработаны явно!

class EllidingEncoder(json.JSONEncoder):
    def encode(self, obj):
        if isinstance(obj, list):
            if len(obj) > 6:
                return "[{:}, …]".format(", ".join([self.encode(i) for i in obj[:6]]))
            else:
                return "[{:}]".format(", ".join([self.encode(i) for i in obj]))
        elif isinstance(obj, dict):
            return "{{{:}}}".format(", ".join(["{:} : {:}".format(k,self.encode(v)) for k,v in obj.items()]))
        else:
            return super(EllidingEncoder, self).encode(obj)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...