Tengo un archivo JSON que es un desastre que quiero imprimir. ¿Cuál es la forma más fácil de hacer esto en Python?
Sé que PrettyPrint toma un "objeto", que creo que puede ser un archivo, pero no sé cómo pasar un archivo. Usar solo el nombre del archivo no funciona.
Puede usar el módulo integrado 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)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))Use esta función y no se preocupe por tener que recordar si su JSON es una str o un dict nuevamente, 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)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.jsonEl módulo json ya implementa algunas impresiones bonitas básicas en las funciones de dump y dumps , con el parámetro de indent que especifica cuántos espacios sangrar:
>>> 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, use json.load() :
with open('filename.txt', 'r') as handle: parsed = json.load(handle)Puedes 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.jsony 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 .
Pygmentize es una herramienta asesina. Mira esto.
Combino python json.tool con pygmentize
echo '{"foo": "bar"}' | python -m json.tool | pygmentize -l jsonConsulte el enlace anterior para obtener instrucciones de instalación de pygmentize.
Una demostración de esto está en la siguiente imagen:
Podrías probar pprintjson .
$ pip3 install pprintjsonBastante 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 }' | pprintjsonBastante 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 1Pretty imprima JSON desde una cadena y guarde la salida en un archivo output.json.
$ pprintjson -c '{ "a": 1, "b": "string", "c": true }' -o ./output.jsondef 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.
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'}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)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.
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))