Как записать данные JSON в файл?
У меня есть данные JSON, хранящиеся в переменной data
.
Я хочу записать это в текстовый файл для тестирования, поэтому мне не нужно каждый раз захватывать данные с сервера.
В настоящее время я пытаюсь это сделать:
obj = open('data.txt', 'wb')
obj.write(data)
obj.close
И я получаю ошибку:
TypeError: must be string or buffer, not dict
Как это исправить?
Ответы
Ответ 1
Вы забыли фактическую часть JSON - data
являются словарем и еще не закодированы в JSON. Напишите это для максимальной совместимости (Python 2 и 3):
import json
with open('data.json', 'w') as f:
json.dump(data, f)
В современной системе (т.е. поддержка Python 3 и UTF-8) вы можете написать более приятный файл с
import json
with open('data.json', 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=4)
Ответ 2
Чтобы получить файл utf8 -encoded в отличие от ascii -encoded в принятом ответе для Python 2, используйте:
import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
f.write(json.dumps(data, ensure_ascii=False))
Код проще в Python 3:
import json
with open('data.txt', 'w') as f:
json.dump(data, f, ensure_ascii=False)
В Windows аргумент encoding='utf-8'
для open
по-прежнему необходим.
Чтобы не хранить зашифрованную копию данных в памяти (результат создания dumps
) и выводить строки байтов utf8 -encoded в Python 2 и 3, используйте:
import json, codecs
with open('data.txt', 'wb') as f:
json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)
codecs.getwriter
является избыточным в Python 3, но требуется для Python 2
Читаемость и размер:
Использование ensure_ascii=False
обеспечивает лучшую читаемость и меньший размер:
>>> 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
Дальнейшее улучшение читабельности путем добавления флагов indent=4, sort_keys=True
(как предложено dinos66) к аргументам dump
или dumps
. Таким образом, вы получите аккуратно отсортированную структуру с отступом в файле json за счет немного большего размера файла.
Ответ 3
Я бы ответил небольшими изменениями с вышеупомянутыми ответами, а именно, чтобы написать префиксный файл JSON, который человеческие глаза могут читать лучше. Для этого пройдите sort_keys
как True
и indent
с 4 пробелами, и вам хорошо идти. Также следите за тем, чтобы коды ascii не записывались в ваш JSON файл:
with open('data.txt', 'w') as outfile:
json.dump(jsonData, outfile, sort_keys = True, indent = 4,
ensure_ascii = False)
Ответ 4
Чтение и запись файлов JSON с помощью Python 2 + 3; работает с юникодом
# -*- coding: utf-8 -*-
import json
# Make it work for Python 2+3 and with Unicode
import io
try:
to_unicode = unicode
except NameError:
to_unicode = str
# Define data
data = {'a list': [1, 42, 3.141, 1337, 'help', u'€'],
'a string': 'bla',
'another dict': {'foo': 'bar',
'key': 'value',
'the answer': 42}}
# Write JSON file
with io.open('data.json', 'w', encoding='utf8') as outfile:
str_ = json.dumps(data,
indent=4, sort_keys=True,
separators=(',', ': '), ensure_ascii=False)
outfile.write(to_unicode(str_))
# Read JSON file
with open('data.json') as data_file:
data_loaded = json.load(data_file)
print(data == data_loaded)
Объяснение параметров json.dump
:
-
indent
: используйте 4 пробела для отступа каждой записи, например, когда начинается новый dict (иначе все будут в одной строке), -
sort_keys
: сортировать ключи словарей. Это полезно, если вы хотите сравнить файлы json с помощью инструмента сравнения/поставить их под контроль версий. -
separators
: чтобы запретить Python добавлять конечные пробелы
С пакетом
Взгляните на мой пакет mpu
для супер простого и легко запоминающегося:
import mpu.io
data = mpu.io.read('example.json')
mpu.io.write('example.json', data)
Создан файл JSON
{
"a list":[
1,
42,
3.141,
1337,
"help",
"€"
],
"a string":"bla",
"another dict":{
"foo":"bar",
"key":"value",
"the answer":42
}
}
Общие окончания файлов
.json
альтернативы
Для вашего приложения может быть важно следующее:
- Поддержка другими языками программирования
- Чтение/запись производительности
- Компактность (размер файла)
Смотрите также: Сравнение форматов сериализации данных
Если вы предпочитаете создавать конфигурационные файлы, вы можете прочитать мою короткую статью Конфигурационные файлы в Python
Ответ 5
Для тех из вас, кто пытается сбросить греческий или другие "экзотические" языки, такие как я, но также испытывает проблемы (ошибки в Unicode) со странными символами, такими как символ мира (\ u262E) или другие, которые часто содержатся в json формирует данные, такие как Twitter, решение может быть следующим (sort_keys, очевидно, необязательно):
import codecs, json
with codecs.open('data.json', 'w', 'utf8') as f:
f.write(json.dumps(data, sort_keys = True, ensure_ascii=False))
Ответ 6
У меня недостаточно репутации для добавления комментариев, поэтому я просто пишу некоторые из моих находок этого раздражающего TypeError:
В принципе, я считаю ошибку в функции json.dump()
только в Python 2 - он не может выгружать данные Python (словарь/список), содержащие символы не ASCII, даже вы открываете файл с параметром encoding = 'utf-8'
. (т.е. независимо от того, что вы делаете). Но json.dumps()
работает как на Python 2, так и на 3.
Чтобы проиллюстрировать это, выполните ответ phihag: код в его ответе разбивается на Python 2 с исключением TypeError: must be unicode, not str
, если data
содержит символы, отличные от 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)
Однако он отлично работает в Python 3.
Ответ 7
Запишите данные в файл, используя JSON, используйте json.dump() или json.dumps().
напишите так, чтобы сохранить данные в файле.
import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
json.dump(data, txtfile)
этот пример в списке хранится в файле.
Ответ 8
json.dump(data, open('data.txt', 'wb'))
Ответ 9
Чтобы написать JSON с отступом "pretty print":
import json
outfile = open('data.json')
json.dump(data, outfile, indent=4)
Кроме того, если вам нужно отладить неправильно отформатированный JSON и получить полезное сообщение об ошибке, используйте библиотеку import simplejson
вместо import json
(функции должны быть такими же)
Ответ 10
если вы пытаетесь записать фреймворк pandas в файл, используя формат json, я бы рекомендовал этот
destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()
Ответ 11
Все предыдущие ответы верны, вот очень простой пример:
#! /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()
![enter image description here]()
Ответ 12
Принятый ответ в порядке. Тем не менее, я столкнулся с ошибкой "не json serializable", используя это.
Вот как я исправил это с помощью open("file-name.json", 'w')
качестве вывода:
output.write(str(response))
Хотя это не очень удачное решение, так как создаваемый файл json не будет содержать двойных кавычек, однако будет неплохо, если вы ищете быстрый и грязный файл.
Ответ 13
Данные JSON могут быть записаны в файл следующим образом
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]}]
Написать в файл:
with open('text1.json', 'w') as f:
json.dump(hist1, f)
Ответ 14
Вот полезная структура для чтения и записи файла в Python 3.
from json import dump, load
from time import sleep
from random import random
def json_file(path, data = None, delay = 0.1):
while True:
try:
if data == None:
with open(path, "r", encoding = "utf-8") as f:
return load(f)
else:
with open(path, "w", encoding = "utf-8") as f:
return dump(data, f)
except:
sleep(random()*delay) # concurrency