¿Cómo imprimir un archivo JSON?
Frecuentes
Visto 1,761 veces
1620
¿Cómo imprimo un archivo JSON en Python?
14 Respuestas
2500
EL json
módulo ya implementa algunas impresiones bonitas básicas en el dump
y dumps
funciones, con el indent
parámetro que especifica cuántos espacios sangrar por:
>>> import json
>>>
>>> your_json = '["foo", {"bar":["baz", null, 1.0, 2]}]'
>>> parsed = json.loads(your_json)
>>> print(json.dumps(parsed, indent=4, sort_keys=True))
[
"foo",
{
"bar": [
"baz",
null,
1.0,
2
]
}
]
Para analizar un archivo, utilice json.load()
:
with open('filename.txt', 'r') as handle:
parsed = json.load(handle)
Respondido el 29 de diciembre de 21 a las 22:12
Para una simple impresión bonita, esto también funciona sin un análisis explícito: print json.dumps(your_json_string, indent=4)
- peterino
Sin la sangría, solo obtienes una sola línea de texto feo, por eso vine aquí. - krs013
Esto es similar a JavaScript var str = JSON.stringify(obj, null, 4);
como se discutió aquí stackoverflow.com/questions/4810841/… - christophe roussy
@Peterino, no funciona sin un análisis explícito. Imprime una línea escapada - LCA
En la herramienta JS más bonita, no agregará 'salto de línea' si el ancho de línea es inferior a 80. Lo estoy buscando. - peterlits zo
427
Puede hacer esto en la línea de comando:
python3 -m json.tool some.json
(como ya se mencionó en los comentarios a la pregunta, gracias a @Kai Petzke por la sugerencia de python3).
En realidad, Python no es mi herramienta favorita en lo que respecta al procesamiento json en la línea de comandos. Para una impresión simple y bonita está bien, pero si desea manipular el json, puede volverse demasiado complicado. Pronto necesitará escribir un archivo de secuencia de comandos separado, podría terminar con mapas cuyas claves son u"alguna clave" (python unicode), lo que dificulta la selección de campos y realmente no va en la dirección de bastante -impresión.
También puedes usar jq:
jq . some.json
y obtienes colores como bonificación (y una extensibilidad mucho más fácil).
Anexo: Hay cierta confusión en los comentarios sobre el uso de jq para procesar archivos JSON grandes por un lado y tener un programa jq muy grande por el otro. Para la impresión bonita de un archivo que consta de una sola entidad JSON grande, la limitación práctica es la memoria RAM. Para la impresión bonita de un archivo de 2 GB que consiste en una sola matriz de datos del mundo real, el "tamaño máximo del conjunto residente" requerido para la impresión bonita era de 5 GB (ya sea que se use jq 1.5 o 1.6). Tenga en cuenta también que jq se puede usar desde Python después de pip install jq
.
Respondido 25 Abr '20, 10:04
JQ es excelente, pero hay un límite máximo, por lo que es inútil para archivos grandes. (es decir, explota al manejar un archivo de 1.15 MB) github.com/stedolan/jq/issues/1041 - Chris McKee
sí, hombre, definitivamente, si estás escribiendo filtros jq con más de 10 XNUMX líneas de código, creo que estás intentando algo como ir a Marte en bicicleta. - gismo ranas
lol :D @gismo-ranas La versión json.tool canalizada a un archivo funciona realmente bien en archivos grandes; y es estúpidamente rápido. Me gusta JQ, pero formatear cualquier cosa más allá de una pequeña carga útil (que podrías hacer en la mayoría de los editores de texto) está fuera de su alcance :) Adición aleatoria: json-generator.com es una buena herramienta para hacer datos de prueba - Chris McKee
o simplemente: jq '' < some.json
- error fatal
En realidad, recomiendo encarecidamente usar python3 -m json.tool <IN >OUT
, ya que esto mantiene el orden original de los campos en los dictados JSON. La versión 2 del intérprete de Python ordena los campos en orden alfabético ascendente, que a menudo no es lo que desea. - Kai Petzke
116
Podrías usar el módulo incorporado pprint (https://docs.python.org/3.9/library/pprint.html).
Cómo puede leer el archivo con datos json e imprimirlo.
import json
import pprint
json_data = None
with open('file_name.txt', 'r') as f:
data = f.read()
json_data = json.loads(data)
print(json_data)
{"firstName": "John", "lastName": "Smith", "isAlive": "true", "age": 27, "address": {"streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021-3100"}, 'children': []}
pprint.pprint(json_data)
{'address': {'city': 'New York',
'postalCode': '10021-3100',
'state': 'NY',
'streetAddress': '21 2nd Street'},
'age': 27,
'children': [],
'firstName': 'John',
'isAlive': True,
'lastName': 'Smith'}
El resultado no es un json válido, porque pprint usa comillas simples y la especificación json requiere comillas dobles.
Si desea reescribir el json con formato de impresión bonita en un archivo, debe usar pprint.pformat.
pretty_print_json = pprint.pformat(json_data).replace("'", '"')
with open('file_name.json', 'w') as f:
f.write(pretty_print_json)
respondido 24 nov., 21:15
El problema con esto es que pprint usará comillas simples y dobles indistintamente, pero json solo requiere comillas dobles, por lo que es posible que su json pprinted ya no se analice como json válido. - drevicko
Sí, pero es solo para generar un archivo json. No tomar la salida y escribirla nuevamente en un archivo. - ikreb
la pregunta dice específicamente que imprima bastante un archivo json, no una representación de Python de un archivo json: Daniel Farrell
@DanielFarrell Tienes razón. Gracias. Actualicé mi respuesta. - ikreb
59
Pygmentize + Python json.tool = Pretty Print con resaltado de sintaxis
Pygmentize es una herramienta asesina. Mira esto.
Combino python json.tool con pygmentize
echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
Consulte el enlace anterior para obtener instrucciones de instalación de pygmentize.
Una demostración de esto está en la siguiente imagen:
Respondido el 30 de enero de 18 a las 09:01
En tu ejemplo -g
en realidad no funciona;) Dado que la entrada proviene de stdin, pygmentize no puede hacer una buena suposición. Debe especificar lexer explícitamente: echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l json
- Denis la amenaza
@DenisTheMenace Solía funcionar en 2015 cuando creé esta imagen de ejemplo. No parece estar funcionando ahora en mi sistema también. - Shubham Chaudhary
45
Usa esta función y no te preocupes por tener que recordar si tu JSON es un str
or dict
de nuevo, solo mire la bonita impresión:
import json
def pp_json(json_thing, sort=True, indents=4):
if type(json_thing) is str:
print(json.dumps(json.loads(json_thing), sort_keys=sort, indent=indents))
else:
print(json.dumps(json_thing, sort_keys=sort, indent=indents))
return None
pp_json(your_json_string_or_dict)
Respondido el 14 de junio de 16 a las 04:06
19
Para poder imprimir bastante desde la línea de comando y poder tener control sobre la sangría, etc., puede configurar un alias similar a este:
alias jsonpp="python -c 'import sys, json; print json.dumps(json.load(sys.stdin), sort_keys=True, indent=2)'"
Y luego use el alias de una de estas maneras:
cat myfile.json | jsonpp
jsonpp < myfile.json
respondido 28 mar '17, 15:03
19
Utilice pprint: https://docs.python.org/3.6/library/pprint.html
import pprint
pprint.pprint(json)
print()
en comparación con pprint.pprint()
print(json)
{'feed': {'title': 'W3Schools Home Page', 'title_detail': {'type': 'text/plain', 'language': None, 'base': '', 'value': 'W3Schools Home Page'}, 'links': [{'rel': 'alternate', 'type': 'text/html', 'href': 'https://www.w3schools.com'}], 'link': 'https://www.w3schools.com', 'subtitle': 'Free web building tutorials', 'subtitle_detail': {'type': 'text/html', 'language': None, 'base': '', 'value': 'Free web building tutorials'}}, 'entries': [], 'bozo': 0, 'encoding': 'utf-8', 'version': 'rss20', 'namespaces': {}}
pprint.pprint(json)
{'bozo': 0,
'encoding': 'utf-8',
'entries': [],
'feed': {'link': 'https://www.w3schools.com',
'links': [{'href': 'https://www.w3schools.com',
'rel': 'alternate',
'type': 'text/html'}],
'subtitle': 'Free web building tutorials',
'subtitle_detail': {'base': '',
'language': None,
'type': 'text/html',
'value': 'Free web building tutorials'},
'title': 'W3Schools Home Page',
'title_detail': {'base': '',
'language': None,
'type': 'text/plain',
'value': 'W3Schools Home Page'}},
'namespaces': {},
'version': 'rss20'}
contestado el 17 de mayo de 19 a las 19:05
pprint
no produce un documento JSON válido. - selurvedu
@selurvedu, ¿qué significa eso y por qué es importante? - Charlie Parker
@CharlieParker Espero que hayan querido decir que saber que tiene un documento JSON válido es bastante útil. Claro, puedes usar el json
módulo para trabajar con los datos y las claves del diccionario funcionan igual con cadenas entre comillas simples o dobles, pero algunas herramientas, por ejemplo Cartero y JSON Editor en línea, ambos esperan que las claves y los valores estén entre comillas dobles (según la especificación JSON). En todo caso, json.org especifica el uso de comillas dobles, que pprint
no produce P.ej pprint.pprint({"name": "Jane"})
produce {'name': 'Jane'}
. - fórmula digital
@CharlieParker, un ejemplo sería el 'language': None,
en el resultado anterior, que debe ser "language": null
. Nota la null
y las comillas dobles. Lo que haces es imprimir bonito un objeto de Python. - Daniel F
Sí, eso es lo que quise decir. Gracias por aclararlo. :-)- selurvedu
9
def saveJson(date,fileToSave):
with open(fileToSave, 'w+') as fileToSave:
json.dump(date, fileToSave, ensure_ascii=True, indent=4, sort_keys=True)
Funciona para mostrarlo o guardarlo en un archivo.
Respondido el 09 de diciembre de 19 a las 16:12
8
Aquí hay un ejemplo simple de una bonita impresión de JSON en la consola de una manera agradable en Python, sin necesidad de que el JSON esté en su computadora como un archivo local:
import pprint
import json
from urllib.request import urlopen # (Only used to get this example)
# Getting a JSON example for this example
r = urlopen("https://mdn.github.io/fetch-examples/fetch-json/products.json")
text = r.read()
# To print it
pprint.pprint(json.loads(text))
Respondido el 23 de enero de 18 a las 08:01
Recibo el siguiente mensaje de error en Python 3: "TypeError: el objeto JSON debe ser str, no 'bytes'" - Mr. T
7
Tu podrías intentar pprintjson.
INSTALACIÓN
$ pip3 install pprintjson
Uso
Bastante imprima JSON desde un archivo usando la CLI de pprintjson.
$ pprintjson "./path/to/file.json"
Pretty imprima JSON desde un stdin usando la CLI de pprintjson.
$ echo '{ "a": 1, "b": "string", "c": true }' | pprintjson
Bastante imprima JSON desde una cadena usando la CLI de pprintjson.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }'
Pretty imprima JSON desde una cadena con una sangría de 1.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -i 1
Pretty imprima JSON desde una cadena y guarde la salida en un archivo output.json.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.json
Salida
Respondido 02 Oct 19, 06:10
¿En qué se diferencia tu sol de import pprint pprint.pprint(json)
? - Charlie Parker
@CharlieParker Creo que produce un documento json válido, a diferencia de pprint, que usa comillas simples en lugar de comillas dobles: TheTechRobo representa a Ucrania
3
Creo que es mejor analizar el json antes, para evitar errores:
def format_response(response):
try:
parsed = json.loads(response.text)
except JSONDecodeError:
return response.text
return json.dumps(parsed, ensure_ascii=True, indent=4)
Respondido 26 Abr '19, 08:04
3
Tenía un requisito similar para volcar el contenido del archivo json para iniciar sesión, algo rápido y fácil:
print(json.dumps(json.load(open(os.path.join('<myPath>', '<myjson>'), "r")), indent = 4 ))
si lo usa a menudo, póngalo en una función:
def pp_json_file(path, file):
print(json.dumps(json.load(open(os.path.join(path, file), "r")), indent = 4))
respondido 12 nov., 20:22
0
Ojalá esto ayude a alguien más.
En el caso de que haya un error de que algo no es json serializable, las respuestas anteriores no funcionarán. Si solo desea guardarlo para que sea legible por humanos, entonces debe llamar recursivamente a la cadena en todos los elementos que no son de diccionario de su diccionario. Si desea cargarlo más tarde, guárdelo como un archivo pickle y luego cárguelo (por ejemplo, torch.save(obj, f)
funciona bien).
Esto es lo que funcionó para mí:
#%%
def _to_json_dict_with_strings(dictionary):
"""
Convert dict to dict with leafs only being strings. So it recursively makes keys to strings
if they are not dictionaries.
Use case:
- saving dictionary of tensors (convert the tensors to strins!)
- saving arguments from script (e.g. argparse) for it to be pretty
e.g.
"""
if type(dictionary) != dict:
return str(dictionary)
d = {k: _to_json_dict_with_strings(v) for k, v in dictionary.items()}
return d
def to_json(dic):
import types
import argparse
if type(dic) is dict:
dic = dict(dic)
else:
dic = dic.__dict__
return _to_json_dict_with_strings(dic)
def save_to_json_pretty(dic, path, mode='w', indent=4, sort_keys=True):
import json
with open(path, mode) as f:
json.dump(to_json(dic), f, indent=indent, sort_keys=sort_keys)
def my_pprint(dic):
"""
@param dic:
@return:
Note: this is not the same as pprint.
"""
import json
# make all keys strings recursively with their naitve str function
dic = to_json(dic)
# pretty print
pretty_dic = json.dumps(dic, indent=4, sort_keys=True)
print(pretty_dic)
# print(json.dumps(dic, indent=4, sort_keys=True))
# return pretty_dic
import torch
# import json # results in non serializabe errors for torch.Tensors
from pprint import pprint
dic = {'x': torch.randn(1, 3), 'rec': {'y': torch.randn(1, 3)}}
my_pprint(dic)
pprint(dic)
salida:
{
"rec": {
"y": "tensor([[-0.3137, 0.3138, 1.2894]])"
},
"x": "tensor([[-1.5909, 0.0516, -1.5445]])"
}
{'rec': {'y': tensor([[-0.3137, 0.3138, 1.2894]])},
'x': tensor([[-1.5909, 0.0516, -1.5445]])}
No sé por qué devolver la cadena y luego imprimirla no funciona, pero parece que debe colocar los volcados directamente en la declaración de impresión. Nota pprint
como se ha sugerido ya funciona también. Tenga en cuenta que no todos los objetos se pueden convertir en un dictado con dict(dic)
es por eso que parte de mi código tiene comprobaciones en esta condición.
Antecedentes:
Quería guardar las cadenas de pytorch pero seguía recibiendo el error:
TypeError: tensor is not JSON serializable
así que codifiqué lo anterior. Tenga en cuenta que sí, en pytorch usa torch.save
pero los archivos pickle no son legibles. Revisa esta publicación relacionada: https://discuss.pytorch.org/t/typeerror-tensor-is-not-json-serializable/36065/3
PPrint también tiene argumentos de sangría, pero no me gustó cómo se ve:
pprint(stats, indent=4, sort_dicts=True)
salida:
{ 'cca': { 'all': {'avg': tensor(0.5132), 'std': tensor(0.1532)},
'avg': tensor([0.5993, 0.5571, 0.4910, 0.4053]),
'rep': {'avg': tensor(0.5491), 'std': tensor(0.0743)},
'std': tensor([0.0316, 0.0368, 0.0910, 0.2490])},
'cka': { 'all': {'avg': tensor(0.7885), 'std': tensor(0.3449)},
'avg': tensor([1.0000, 0.9840, 0.9442, 0.2260]),
'rep': {'avg': tensor(0.9761), 'std': tensor(0.0468)},
'std': tensor([5.9043e-07, 2.9688e-02, 6.3634e-02, 2.1686e-01])},
'cosine': { 'all': {'avg': tensor(0.5931), 'std': tensor(0.7158)},
'avg': tensor([ 0.9825, 0.9001, 0.7909, -0.3012]),
'rep': {'avg': tensor(0.8912), 'std': tensor(0.1571)},
'std': tensor([0.0371, 0.1232, 0.1976, 0.9536])},
'nes': { 'all': {'avg': tensor(0.6771), 'std': tensor(0.2891)},
'avg': tensor([0.9326, 0.8038, 0.6852, 0.2867]),
'rep': {'avg': tensor(0.8072), 'std': tensor(0.1596)},
'std': tensor([0.0695, 0.1266, 0.1578, 0.2339])},
'nes_output': { 'all': {'avg': None, 'std': None},
'avg': tensor(0.2975),
'rep': {'avg': None, 'std': None},
'std': tensor(0.0945)},
'query_loss': { 'all': {'avg': None, 'std': None},
'avg': tensor(12.3746),
'rep': {'avg': None, 'std': None},
'std': tensor(13.7910)}}
comparar con:
{
"cca": {
"all": {
"avg": "tensor(0.5144)",
"std": "tensor(0.1553)"
},
"avg": "tensor([0.6023, 0.5612, 0.4874, 0.4066])",
"rep": {
"avg": "tensor(0.5503)",
"std": "tensor(0.0796)"
},
"std": "tensor([0.0285, 0.0367, 0.1004, 0.2493])"
},
"cka": {
"all": {
"avg": "tensor(0.7888)",
"std": "tensor(0.3444)"
},
"avg": "tensor([1.0000, 0.9840, 0.9439, 0.2271])",
"rep": {
"avg": "tensor(0.9760)",
"std": "tensor(0.0468)"
},
"std": "tensor([5.7627e-07, 2.9689e-02, 6.3541e-02, 2.1684e-01])"
},
"cosine": {
"all": {
"avg": "tensor(0.5945)",
"std": "tensor(0.7146)"
},
"avg": "tensor([ 0.9825, 0.9001, 0.7907, -0.2953])",
"rep": {
"avg": "tensor(0.8911)",
"std": "tensor(0.1571)"
},
"std": "tensor([0.0371, 0.1231, 0.1975, 0.9554])"
},
"nes": {
"all": {
"avg": "tensor(0.6773)",
"std": "tensor(0.2886)"
},
"avg": "tensor([0.9326, 0.8037, 0.6849, 0.2881])",
"rep": {
"avg": "tensor(0.8070)",
"std": "tensor(0.1595)"
},
"std": "tensor([0.0695, 0.1265, 0.1576, 0.2341])"
},
"nes_output": {
"all": {
"avg": "None",
"std": "None"
},
"avg": "tensor(0.2976)",
"rep": {
"avg": "None",
"std": "None"
},
"std": "tensor(0.0945)"
},
"query_loss": {
"all": {
"avg": "None",
"std": "None"
},
"avg": "tensor(12.3616)",
"rep": {
"avg": "None",
"std": "None"
},
"std": "tensor(13.7976)"
}
}
Respondido 16 Feb 21, 18:02
-8
Está lejos de ser perfecto, pero hace el trabajo.
data = data.replace(',"',',\n"')
puede mejorarlo, agregar sangría, etc., pero si solo desea poder leer un json más limpio, este es el camino a seguir.
Respondido 01 Abr '20, 15:04
AttributeError: el objeto 'dict' no tiene el atributo 'replace' - AjayKumarBasuthkar
¿No estropeará esto el archivo si tiene una coma en una cadena? - TheTechRobo representa a Ucrania
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas python json formatting pretty-print or haz tu propia pregunta.
Intenta analizar el JSON usando
json.loads()
e imprima bastante ese diccionario resultante. O simplemente salta a la Bonita impresión sección de Python documentación parajson
. - Blenderstackoverflow.com/questions/352098/… - ed.
@Blender si publica una respuesta, le daré crédito ... esto podría cerrarse como un duplicado, porque la solución es la misma, pero la pregunta es diferente, así que quizás no. - Colleen
Por qué no
<your_file.js python -mjson.tool
como en el enlace de @ed? - jfsNo creo que esté duplicado porque la impresión bonita desde la línea de comandos no es lo mismo que la impresión bonita mediante programación desde Python. Votación para reabrir. - vitaut