JSONデータをファイルに書き込むにはどうすればよいですか?


1122

変数にJSONデータが格納されていますdata

テストのためにこれをテキストファイルに書き込みたいので、毎回サーバーからデータを取得する必要はありません。

現在、私はこれを試しています:

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

そして、私はこのエラーを受け取っています:

TypeError:辞書ではなく文字列またはバッファでなければなりません

これを修正するには?

回答:


2041

実際の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)

8
これは、シリアル化のために役立つかもしれない:stackoverflow.com/questions/4512982/...を
jedierikb

12
json.dumpまたはjson.dumpsを意味しますか?
TerminalDilettante

153
@TerminalDilettante json.dumpはファイルまたはファイルのようなオブジェクトに書き込みjson.dumpsますが、文字列を返します。
phihag

24
btw:データを再度読み取るには、open( 'data.txt')をinfileとして使用します:d = json.load(infile)。参照:この回答
klaas

9
@denvarいいえ、この回答は微調整されています。Python 3ではjson.dump、バイナリファイルではなくテキストファイルに書き込みます。TypeErrorファイルがで開かれた場合、を取得しますwb。古いPythonのバージョンでは、両方wのNAND wb作品。の出力はjson.dumpデフォルトでASCIIのみであるため、明示的なエンコードは必要ありません。コードがレガシーPythonバージョンで実行されないことが確実で、JSONファイルのハンドラーが非ASCIIデータを正しく処理できる場合は、1つを指定してを設定できますensure_ascii=False
phihag

267

Python 2の承認された回答でascii -encodedとは対照的にutf8 -encodedファイルを取得するには、次を使用します。

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)、Python 2と3の両方でutf8エンコードされたバイト文字列を出力するには、次のコマンドを使用します。

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=Truedinos66で提案)。このようにすると、ファイルサイズがわずかに大きくなりますが、jsonファイルでうまくインデントされたソート構造が得られます。dumpdumps


5
unicode余分である-の結果はjson.dumps、すでにUnicodeオブジェクトです。これは、出力ファイルモードのこの混乱全体がクリーンアップされた3.xでは失敗し、jsonは常にバイトではなく文字列(および文字I / O)を使用することに注意してください。
phihag 2013

4
2.xではtype(json.dumps('a'))です<type 'str'>。でもtype(json.dumps('a', encoding='utf8'))です<type 'str'>
アントニーハッチキンズ2013

4
はい、3.xではjsonは文字列を使用しますが、デフォルトのエンコーディングはasciiです。utf83.xでも必要であることを明示的に伝える必要があります。回答を更新しました。
アントニーハッチキンズ2013

4
ああ、あなたは完全に正しいです-私は何かを混乱させたに違いありません。詳細は+1。
phihag 2013

1
Python 3.xの回答は、2.7を使用している場合でも機能しました。2.xの回答でエラーが返されました:'ascii' codec can't decode byte 0xf1 in position 506755: ordinal not in range(128)。疑問がある場合は、3.xの答えを使用してください。
Blairg23、2015

162

私は前述の回答を少し変更して回答します。それは、人間の目でよりよく読み取れる、美化されたJSONファイルを書き込むことです。これには、4つのスペース文字をsort_keysそのまま渡してTrue、問題indentありません。また、ASCIIコードがJSONファイルに書き込まれないように注意してください。

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

2
まだ取得中UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc'
stevek

1
@SirBenBenji記述しようとしている文字列がstr.decode( 'utf-8')であることを確認します。
ambodi 2015

1
@SirBenBenji dinos66で以下に指定されているように、コーデックも使用できます
Shiv

また# -*- coding: utf-8 -*-、シバンの後に追加してエンコードを宣言する必要があります
aesede

2
sort_keysとインデントの場合は+1。@aesedeこの行を追加しても、このソリューションはpython2でも機能するように見えます(UnicodeEncodeError非ASCIIデータの場合)。詳細については、私のソリューションを参照してください。
アントニーハッチキンズ2017

111

Python 2 + 3でJSONファイルを読み書きします。ユニコードで動作します

# -*- 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つのスペースを使用して各エントリをインデントします。たとえば、新しい辞書が開始されたとき(そうでない場合、すべてが1行になります)、
  • sort_keys:辞書のキーをソートします。これは、jsonファイルをdiffツールと比較したり、バージョン管理下に置いたりする場合に便利です。
  • 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での構成ファイル」を読んでください。


2
force_asciiフラグはTrueデフォルトであることに注意してください。jsonファイル(およびその他の非ASCII文字)には、"\u20ac"それぞれに読み取り不可能な6バイトのシーケンスがあります。
アントニーハッチキンズ2017

なぜあなたopenは読み書きのために使うのio.openですか?それが可能に使用するio.openだけでなく読み取るため?その場合、どのパラメーターを渡す必要がありますか?
Micah Zoltu 2017年

23

ギリシャ語または私などの他の「エキゾチックな」言語をダンプしようとしているが、平和記号(\ u262E)などの奇妙な文字(json形式のデータに含まれることが多い)で問題(Unicodeエラー)が発生している方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))

1
+1 docsは組み込みopenのpython3および関連するを推奨io.openしていますcodecs.openが、この場合は下位互換性のあるハックとしても優れています。python2ではio.open codecs.openよりも「雑食性」です(strとunicodeの両方を「食べる」ことができ、必要に応じて変換できます)。このcodecs.open癖は、入力にUnicode文字列が存在するかどうかに応じて、json.dumpsさまざまな種類のオブジェクト(str/ unicode)を生成する癖を補うと言えます。
アントニーハッチキンズ2017

10

私はコメントを追加するのに十分な評判がないので、この迷惑なTypeErrorの私の発見のいくつかをここに書きます:

基本的に、それjson.dump()はPython 2の関数のバグだと思います- パラメータを使用してファイルを開いて、非ASCII文字を含むPython(辞書/リスト)データをダンプできませんencoding = 'utf-8'。(つまり、何をしても)。ただし、json.dumps()Python 2と3の両方で動作します。

これを説明するために、phihagの回答をフォローアップします。彼の回答のコードは、ASCII以外の文字が含まれているTypeError: must be unicode, not str場合を除いて、Python 2で中断しdataます。(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では正常に動作します。


何かが間違っていると主張するときは理由を挙げてください。@nicknameを使用して、その人に通知されるようにします。コメントを書くことはできませんが、コメントを読むことはできます。最初のコメントに対する私の回答ですでに述べたように、を試してくださいdata = {'asdf': 1}TypeError(2番目の)バリアントで悪名高くなります。
アントニーハッチキンズ2017

に関してensure_ascii-「実際の」utf8出力を取得したい場合に必要です。それがなければ、このフラグのある文字ごとに2バイトではなく、ロシア文字ごとに6バイトの単純なASCIIになります。
アントニーハッチキンズ2017

@AntonyHatchkinsあなたはそのunicode()部分に適しています。私はちょうどのために実現しio、Pythonの2パッケージwrite()必要unicode、ありませんstr
ibic

1
このコードはpython2.6.6、Debian(2010年12月10日)でも機能します。python2.7.9またはpython3と同様。もう一度確認してください、plz。
アントニーハッチキンズ2017

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)

リストのこの例は、ファイルに保存されています。


似ていますが、例を示します
Vishal Gediya

5

インデント付きのJSONを書くには、「きれいな印刷」:

import json

outfile = open('data.json')
json.dump(data, outfile, indent=4)

また、不適切にフォーマットされたJSONをデバッグする必要があり、有用なエラーメッセージが必要な場合はimport simplejson、代わりにライブラリを使用してimport jsonください(関数は同じである必要があります)


4
json.dump(data, open('data.txt', 'wb'))

2
これは@phihagの答えと同じことを行いますが、常に機能することは保証されていません。そのようなコードを考えてみましょう:f = open('1.txt', 'w'); f.write('a'); input()。それを実行してから(それをSYGTERM Ctrl-Z、その後kill %1、Linux上でCtrl-BreakWindows上で)。1.txt0バイトになります。これは、SYGTERMが発生した時点で、書き込みがバッファリングされ、ファイルもフラッシュされず閉じられなかったためです。withblockは、「try / finally」ブロックと同じようにファイルが常に閉じられることを保証しますが、ブロックは短くなります。
アントニーハッチキンズ2017

3

JSONをファイルに書き込む

import json

data = {}
data['people'] = []
data['people'].append({
    'name': 'Scott',
    'website': 'stackabuse.com',
    'from': 'Nebraska'
})
data['people'].append({
    'name': 'Larry',
    'website': 'google.com',
    'from': 'Michigan'
})
data['people'].append({
    'name': 'Tim',
    'website': 'apple.com',
    'from': 'Alabama'
})

with open('data.txt', 'w') as outfile:
    json.dump(data, outfile)

ファイルからのJSONの読み取り

import json

with open('data.txt') as json_file:
    data = json.load(json_file)
    for p in data['people']:
        print('Name: ' + p['name'])
        print('Website: ' + p['website'])
        print('From: ' + p['from'])
        print('')

Stack Overflowへようこそ。十分に確立された正しい回答のある古い質問に回答することにした場合、その日の後半に新しい回答を追加しても、クレジットを得られない可能性があります。特徴的な新しい情報がある場合、または他の回答がすべて間違っていると確信している場合は、必ず新しい回答を追加してください。あなたに多くの信用を与えます。(あなたはいくつかのサンプルデータを示しています;それは良いです、しかし、特にあなたがサンプルデータのために生成されたものを示さないので、それは十分であると私は確信していません。)
Jonathan Leffler '26

ガイダンスに感謝
iman

2

あなたがパンダデータフレームをjsonフォーマットを使用してファイルに書き込もうとしているなら、私はこれをお勧めします

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()

2

これまでのすべての答えは正しいです。ここでは非常に単純な例を示します。

#! /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()

ここに画像の説明を入力してください


1

受け入れられた答えは結構です。しかし、それを使用すると「is json serializable」エラーが発生しました。

これがopen("file-name.json", 'w')出力として修正した方法です:

output.write(str(response))

作成されるjsonファイルには二重引用符が含まれないため、これは適切な修正ではありませんが、迅速かつダーティなものを探している場合は最適です。


0

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)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.