Como escrevo os dados do JSON para um arquivo?

Eu tenho dados JSON armazenados na variável dados.

Eu quero escrever isso em um arquivo de texto para teste, então eu não'não tenho que pegar os dados do servidor a cada vez.

Neste momento, estou a tentar isto:

obj = open('data.txt', 'wb')
obj.write(data)
obj.close

E estou a receber o erro:

"TypeError: deve ser string ou buffer, não dict".

Como resolver isto?

Solução

Você esqueceu a parte real do JSON - dados é um dicionário e ainda não está codificado no JSON. Escreva-o assim para máxima compatibilidade (Python 2 e 3):

import json
with open('data.json', 'w') as f:
    json.dump(data, f)

Num sistema moderno (isto é, suporte Python 3 e UTF-8), você pode escrever um arquivo mais agradável com

import json
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=4)
Comentários (21)

Para obter o arquivo utf8-encoded em oposição ao ascii-encoded na resposta aceita para uso em Python 2:

import io, json
with io.open('data.txt', 'w', encoding='utf-8') as f:
  f.write(json.dumps(data, ensure_ascii=False))

O código é mais simples em Python 3:

import json
with open('data.txt', 'w') as f:
  json.dump(data, f, ensure_ascii=False)

No Windows, o encoding='utf-8' argument to `open'' ainda é necessário.

Para evitar o armazenamento de uma cópia codificada dos dados na memória (resultado de `dumps') e para sair utf8-encoded bytestrings tanto em Python 2 como 3, utilize:

import json, codecs
with open('data.txt', 'wb') as f:
    json.dump(data, codecs.getwriter('utf-8')(f), ensure_ascii=False)

A chamada `codecs.getwriter' é redundante em Python 3, mas necessária para Python 2.


Releitura e tamanho:

A utilização de ensure_ascii=False proporciona uma melhor legibilidade e um tamanho menor:

>>> 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

Melhora ainda mais a legibilidade adicionando bandeiras indent=4, sort_keys=True (como sugerido por dinos66) aos argumentos de dump ou dumps. Desta forma você terá uma estrutura ordenada e bem indentada no arquivo json ao custo de um arquivo de tamanho um pouco maior.

Comentários (18)

Eu responderia com ligeiras modificações com as respostas acima mencionadas e isso é para escrever um arquivo JSON pré-estabelecido que os olhos humanos possam ler melhor. Para isso, passe sort_keys' comoTrue' e `indent' com 4 caracteres de espaço e você está pronto para ir. Tenha também o cuidado de garantir que os códigos ascii não serão escritos no seu arquivo JSON:

with open('data.txt', 'w') as outfile:
     json.dump(jsonData, outfile, sort_keys = True, indent = 4,
               ensure_ascii = False)
Comentários (5)