Я хочу вывести несколько больших файлов 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)