Tengo datos JSON almacenados en los data
variables.
Quiero escribir esto en un archivo de texto para probarlo, así no tengo que tomar los datos del servidor cada vez.
Actualmente, estoy intentando esto:
obj = open('data.txt', 'wb') obj.write(data) obj.close
Y estoy recibiendo este error:
TypeError: debe ser cadena o búfer, no dict
¿Cómo arreglar esto?
Esta es solo una pista adicional sobre el uso de json.dumps
(esta no es una respuesta al problema de la pregunta, sino un truco para aquellos que tienen que volcar tipos de datos numpy):
Si hay tipos de datos NumPy en el diccionario, json.dumps()
necesita un parámetro adicional, los créditos van a TypeError: Object of type 'ndarray' is not JSON serializable , y también corregirá errores como TypeError: Object of type int64 is not JSON serializable
y así sucesivamente:
class NumpyEncoder(json.JSONEncoder): """ Special json encoder for np types """ def default(self, obj): if isinstance(obj, (np.int_, np.intc, np.intp, np.int8, np.int16, np.int32, np.int64, np.uint8, np.uint16, np.uint32, np.uint64)): return int(obj) elif isinstance(obj, (np.float_, np.float16, np.float32, np.float64)): return float(obj) elif isinstance(obj, (np.ndarray,)): return obj.tolist() return json.JSONEncoder.default(self, obj)
Y luego ejecuta:
import json #print(json.dumps(my_data[:2], indent=4, cls=NumpyEncoder))) with open(my_dir+'/my_filename.json', 'w') as f: json.dumps(my_data, indent=4, cls=NumpyEncoder)))
También es posible que desee devolver una cadena en lugar de una lista en el caso de np.array(), ya que las matrices se imprimen como listas que se distribuyen en filas, lo que aumentará la salida si tiene muchas matrices. La advertencia: es más difícil acceder a los elementos del diccionario volcado más tarde para recuperarlos como la matriz original. Sin embargo, si no le importa tener solo una cadena de una matriz, esto hace que el diccionario sea más legible. Luego intercambia:
elif isinstance(obj, (np.ndarray,)): return obj.tolist()
con:
elif isinstance(obj, (np.ndarray,)): return str(obj)
o solo:
else: return str(obj)
Para escribir el JSON con sangría, "impresión bonita":
import json outfile = open('data.json') json.dump(data, outfile, indent=4)
Además, si necesita depurar JSON con formato incorrecto y desea un mensaje de error útil, use la biblioteca import simplejson
, en lugar de import json
(las funciones deben ser las mismas)
Los datos JSON se pueden escribir en un archivo de la siguiente manera
hist1 = [{'val_loss': [0.5139984398465246], 'val_acc': [0.8002029867684085], 'loss': [0.593220705309384], 'acc': [0.7687131817929321]}, {'val_loss': [0.46456472964199463], 'val_acc': [0.8173602046780344], 'loss': [0.4932038113037539], 'acc': [0.8063946213802453]}]
Escribir en un archivo:
with open('text1.json', 'w') as f: json.dump(hist1, f)
Escriba datos en un archivo usando JSON, use json.dump() o json.dumps() . escriba así para almacenar datos en el archivo.
import json data = [1,2,3,4,5] with open('no.txt', 'w') as txtfile: json.dump(data, txtfile)
este ejemplo en la lista se almacena en un archivo.
Olvidó la parte JSON real: data
son un diccionario y aún no están codificados en JSON. Escríbalo así para máxima compatibilidad (Python 2 y 3):
import json with open('data.json', 'w') as f: json.dump(data, f)
En un sistema moderno (es decir, compatible con Python 3 y UTF-8), puede escribir un archivo más agradable con
import json with open('data.json', 'w', encoding='utf-8') as f: json.dump(data, f, ensure_ascii=False, indent=4)
Para obtener un archivo codificado en utf8 en lugar de codificado en ascii en la respuesta aceptada para el uso de Python 2:
import io, json with io.open('data.txt', 'w', encoding='utf-8') as f: f.write(json.dumps(data, ensure_ascii=False))
El código es más simple en Python 3:
import json with open('data.txt', 'w') as f: json.dump(data, f, ensure_ascii=False)
En Windows, el argumento encoding='utf-8'
para open
sigue siendo necesario.
Para evitar almacenar una copia codificada de los datos en la memoria (resultado de los dumps
) y generar cadenas de bytes codificadas en utf8 en Python 2 y 3, use:
import json, codecs with open('data.txt', 'wb') as f: json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)
La llamada codecs.getwriter
es redundante en Python 3 pero requerida para Python 2
Legibilidad y tamaño:
El uso de ensure_ascii=False
brinda una mejor legibilidad y un tamaño más pequeño:
>>> json.dumps({'price': '€10'}) '{"price": "\\u20ac10"}' >>> json.dumps({'price': '€10'}, ensure_ascii=False) '{"price": "€10"}' >>> len(json.dumps({'абвгд': 1})) 37 >>> len(json.dumps({'абвгд': 1}, ensure_ascii=False).encode('utf8')) 17
Mejore aún más la legibilidad agregando flags indent=4, sort_keys=True
(como lo sugiere dinos66 ) a los argumentos de dump
o dumps
. De esta manera, obtendrá una estructura ordenada con una buena sangría en el archivo json a costa de un tamaño de archivo ligeramente mayor.
Respondería con una ligera modificación con las respuestas antes mencionadas y eso es escribir un archivo JSON embellecido que los ojos humanos puedan leer mejor. Para esto, pase sort_keys
como True
y indent
con 4 caracteres de espacio y estará listo para comenzar. También asegúrese de que los códigos ascii no se escriban en su archivo JSON:
with open('data.txt', 'w') as outfile: json.dump(jsonData, outfile, sort_keys = True, indent = 4, ensure_ascii = False)
Para aquellos de ustedes que están tratando de deshacerse del griego u otros idiomas "exóticos" como yo, pero también tienen problemas (errores Unicode) con caracteres extraños como el símbolo de la paz (\u262E) u otros que a menudo están contenidos en datos con formato json como la de Twitter, la solución podría ser la siguiente (sort_keys es obviamente opcional):
import codecs, json with codecs.open('data.json', 'w', 'utf8') as f: f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))
No tengo suficiente reputación para agregar comentarios, así que solo escribo algunos de mis hallazgos de este molesto TypeError aquí:
Básicamente, creo que es un error en la función json.dump()
solo en Python 2 : no puede volcar datos de Python (diccionario/lista) que contengan caracteres que no sean ASCII, incluso si abre el archivo con la encoding = 'utf-8'
parámetro. (es decir, no importa lo que hagas). Pero, json.dumps()
funciona tanto en Python 2 como en 3.
Para ilustrar esto, siguiendo la respuesta de phihag: el código en su respuesta se rompe en Python 2 con la excepción TypeError: must be unicode, not str
, si data
contienen caracteres que no son ASCII. (Python 2.7.6, Debian):
import json data = {u'\u0430\u0431\u0432\u0433\u0434': 1} #{u'абвгд': 1} with open('data.txt', 'w') as outfile: json.dump(data, outfile)
Sin embargo, funciona bien en Python 3.
json.dump(data, open('data.txt', 'wb'))
si está tratando de escribir un marco de datos de pandas en un archivo usando un formato json, le recomendaría esto
destination='filepath' saveFile = open(destination, 'w') saveFile.write(df.to_json()) saveFile.close()
Todas las respuestas anteriores son correctas aquí hay un ejemplo muy simple:
#! /usr/bin/env python import json def write_json(): # create a dictionary student_data = {"students":[]} #create a list data_holder = student_data["students"] # just a counter counter = 0 #loop through if you have multiple items.. while counter < 3: data_holder.append({'id':counter}) data_holder.append({'room':counter}) counter += 1 #write the file file_path='/tmp/student_data.json' with open(file_path, 'w') as outfile: print("writing file to: ",file_path) # HERE IS WHERE THE MAGIC HAPPENS json.dump(student_data, outfile) outfile.close() print("done") write_json()
La respuesta aceptada está bien. Sin embargo, me encontré con el error "no es json serializable" al usar eso.
Así es como lo arreglé con open("file-name.json", 'w')
como salida:
output.write(str(response))
Aunque no es una buena solución, ya que el archivo json que crea no tendrá comillas dobles, sin embargo, es excelente si está buscando algo rápido y sucio.