Eu tenho dados JSON armazenados na variável data
.
Quero gravar isso em um arquivo de texto para teste, para que não precise pegar os dados do servidor todas as vezes.
Atualmente, estou tentando o seguinte:
obj = open('data.txt', 'wb')
obj.write(data)
obj.close
E estou recebendo este erro:
TypeError: deve ser string ou buffer, não dict
Como consertar isto?
json.dump
grava em um arquivo ou objeto semelhante a um arquivo, enquantojson.dumps
retorna uma string.json.dump
grava em um arquivo de texto, não em um arquivo binário. Você receberia umTypeError
se o arquivo fosse aberto comwb
. Em versões mais antigas do Python, tantow
newb
trabalho. Uma codificação explícita não é necessária, pois a saída dejson.dump
é apenas ASCII por padrão. Se você pode ter certeza de que seu código nunca é executado nas versões herdadas do Python e você e o manipulador do arquivo JSON podem manipular corretamente dados não ASCII, você pode especificar um e definirensure_ascii=False
.Para obter o arquivo codificado em utf8 em vez de codificado em ascii na resposta aceita para o Python 2, use:
O código é mais simples no Python 3:
No Windows, o
encoding='utf-8'
argumento paraopen
ainda é necessário.Para evitar o armazenamento de uma cópia codificada dos dados na memória (resultado de
dumps
) e a saída de seqüências de caracteres codificadas em utf8 no Python 2 e 3, use:A
codecs.getwriter
chamada é redundante no Python 3, mas necessária para o Python 2Legibilidade e tamanho:
O uso de
ensure_ascii=False
fornece melhor legibilidade e tamanho menor:Melhore ainda mais a legibilidade adicionando sinalizadores
indent=4, sort_keys=True
(como sugerido por dinos66 ) aos argumentos dedump
oudumps
. Dessa forma, você obterá uma estrutura ordenada bem recuada no arquivo json ao custo de um tamanho de arquivo um pouco maior.fonte
unicode
é supérfluo - o resultado dejson.dumps
já é um objeto unicode. Observe que isso falha no 3.x, onde toda essa bagunça do modo de arquivo de saída foi limpa, e o json sempre usa cadeias de caracteres (e E / S de caracteres) e nunca bytes.type(json.dumps('a'))
é<type 'str'>
. Eventype(json.dumps('a', encoding='utf8'))
is<type 'str'>
.utf8
mesmo no 3.x. Atualizado a resposta.'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)
. Portanto, quando estiver em dúvida, use a resposta 3.x!Eu responderia com ligeiras modificações com as respostas acima mencionadas e isso é para escrever um arquivo JSON prettificado que os olhos humanos possam ler melhor. Para isso, passe
sort_keys
comoTrue
eindent
com 4 caracteres de espaço e você estará pronto. Também verifique se os códigos ascii não serão gravados no seu arquivo JSON:fonte
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc'
# -*- coding: utf-8 -*-
após o shebangUnicodeEncodeError
com dados não-ascii). Veja minha solução para detalhes.Leia e grave arquivos JSON com Python 2 + 3; trabalha com unicode
Explicação dos parâmetros de
json.dump
:indent
: Use 4 espaços para recuar cada entrada, por exemplo, quando um novo ditado é iniciado (caso contrário, todos estarão em uma linha),sort_keys
: classifica as chaves dos dicionários. Isso é útil se você deseja comparar arquivos json com uma ferramenta diff / colocá-los sob controle de versão.separators
: Para impedir que o Python adicione espaços em branco à direitaCom um pacote
Dê uma olhada no meu pacote de utilitários
mpu
para obter um super simples e fácil de lembrar:Arquivo JSON criado
Finais de arquivos comuns
.json
Alternativas
Para seu aplicativo, o seguinte pode ser importante:
Consulte também: Comparação de formatos de serialização de dados
Caso você esteja procurando uma maneira de criar arquivos de configuração, leia meu pequeno artigo Arquivos de configuração em Python
fonte
force_ascii
sinalizador éTrue
por padrão. Você terá"\u20ac"
sequências ilegíveis de 6 bytes para cada€
arquivo json (assim como qualquer outro caractere não-ascii).open
para a leitura, masio.open
para escrever? Também é possível usario.open
para leitura? Se sim, quais parâmetros devem ser passados?Para aqueles que estão tentando despejar grego ou outras línguas "exóticas", como eu, mas também estão tendo problemas (erros unicode) com caracteres estranhos, como o símbolo de paz (\ u262E) ou outros que geralmente estão contidos em dados formatados por json como no Twitter, a solução pode ser a seguinte (sort_keys é obviamente opcional):
fonte
open
eo assotiatedio.open
maiscodecs.open
, neste caso, também é um hack agradáveis compatível com versões anteriores. Em python2codecs.open
é mais "onívoro" que io.open (pode "comer" str e unicode, convertendo se necessário). Pode-se dizer que essacodecs.open
peculiaridade compensa ajson.dumps
peculiaridade de gerar diferentes tipos de objetos (str
/unicode
) dependendo da presença das cadeias unicode na entrada.Como não tenho reputação suficiente para adicionar comentários, escrevo aqui algumas das minhas descobertas sobre este TypeError irritante:
Basicamente, acho que é um bug na
json.dump()
função somente no Python 2 - ele não pode despejar dados do Python (dicionário / lista) contendo caracteres não ASCII, mesmo que você abra o arquivo com oencoding = 'utf-8'
parâmetro (ou seja, não importa o que você faça). Mas,json.dumps()
funciona em Python 2 e 3.Para ilustrar isso, acompanhando a resposta de phihag: o código em sua resposta quebra no Python 2 com exceção
TypeError: must be unicode, not str
, sedata
contiver caracteres não ASCII. (Python 2.7.6, Debian):No entanto, funciona bem em Python 3.
fonte
data = {'asdf': 1}
. Você obterá o notórioTypeError
com sua (segunda) variante.ensure_ascii
que diz respeito - é necessário se você deseja obter uma saída utf8 "real". Sem ele, você terá ascii simples com 6 bytes por letra russa, em vez de 2 bytes por caractere com esse sinalizador.unicode()
parte. Acabei de perceber para oio
pacote em Python 2,write()
necessidadesunicode
, nãostr
.Grave dados no arquivo usando JSON, use json.dump () ou json.dumps () usado. escreva assim para armazenar dados em arquivo.
este exemplo na lista é armazenado em um arquivo.
fonte
Para escrever o JSON com recuo, "pretty print":
Além disso, se você precisar depurar JSON formatado incorretamente e desejar uma mensagem de erro útil, use a
import simplejson
biblioteca, em vez deimport json
(as funções devem ser as mesmas)fonte
fonte
f = open('1.txt', 'w'); f.write('a'); input()
. Execute-o e depois SYGTERM-lo (Ctrl-Z
depoiskill %1
no Linux,Ctrl-Break
no Windows).1.txt
terá 0 bytes. Isso ocorre porque a gravação foi armazenada em buffer e o arquivo não foi liberado e não foi fechado no momento em que ocorreu o SYGTERM.with
O bloco garante que o arquivo sempre seja fechado da mesma forma que o bloco 'try / finally', mas menor.Gravando JSON em um arquivo
Lendo JSON de um arquivo
fonte
se você estiver tentando gravar um dataframe do pandas em um arquivo usando o formato json, eu recomendaria isso
fonte
Todas as respostas anteriores estão corretas aqui é um exemplo muito simples:
fonte
A resposta aceita é boa. No entanto, eu encontrei o erro "não é json serializable" usando isso.
Aqui está como eu o consertei
open("file-name.json", 'w')
como saída:output.write(str(response))
Embora não seja uma boa solução, o arquivo json que ele cria não terá aspas duplas, mas é ótimo se você estiver procurando rápido e sujo.
fonte
Os dados JSON podem ser gravados em um arquivo da seguinte maneira
Escreva em um arquivo:
fonte