1445

変数にJSONデータを保存していますdata

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

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

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

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

TypeError:dictではなく文字列またはバッファである必要があります

これを修正する方法は?

4

14 に答える 14

2604

実際の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)
于 2012-09-06T22:23:14.897 に答える
285

Python 2で受け入れられている回答で、ASCIIでエンコードされたファイルではなくutf8でエンコードされたファイルを取得するには、次のようにします。

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はまだ必要です。

データのエンコードされたコピー(の結果)をメモリに保存しないようにし、Python 2と3の両方でutf8でエンコードされdumpsたバイト文字列を出力するには、次を使用します。

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

このcodecs.getwriter呼び出しはPython3では冗長ですが、Python2では必要です


読みやすさとサイズ:

を使用すると、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

于 2013-02-14T08:22:36.483 に答える
173

私は前述の答えを少し変更して答えます。それは、人間の目がよりよく読めるように、きれいなJSONファイルを作成することです。このために、4つのスペース文字をそのまま通過させれば、準備は完了ですsort_keys。また、ASCIIコードがJSONファイルに書き込まれないように注意してください。Trueindent

with open('data.txt', 'w') as outfile:
     json.dump(jsonData, outfile, sort_keys = True, indent = 4,
               ensure_ascii = False)
于 2013-12-25T20:04:24.653 に答える
125

Python 2+3でJSONファイルを読み書きします。Unicodeで動作します

# -*- 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が開始されたとき(そうでない場合は、すべてが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での構成ファイル」を読むことをお勧めします。

于 2016-06-13T16:43:33.533 に答える
26

ギリシャ語や私のような他の「エキゾチック」な言語をダンプしようとしているが、平和の記号(\ 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))
于 2015-07-10T14:45:29.270 に答える
13

コメントを追加するのに十分な評判がないので、この厄介なTypeErrorの発見のいくつかをここに書きます。

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

これを説明するために、phihagの答えをフォローアップします。彼の答えのコードは、非ASCII文字が含まれているTypeError: must be unicode, not str場合、例外を除いてPython2で壊れます。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)

ただし、Python3では正常に機能します。

于 2016-01-03T06:52:36.360 に答える
11

JSONを使用してファイルにデータを書き込みます。json.dump()またはjson.dumps()を使用します。このように記述して、データをファイルに保存します。

import json
data = [1,2,3,4,5]
with open('no.txt', 'w') as txtfile:
    json.dump(data, txtfile)

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

于 2015-12-24T10:58:21.390 に答える
6
json.dump(data, open('data.txt', 'wb'))
于 2016-02-29T20:16:51.557 に答える
6

インデント付きのJSONを作成するには、「きれいに印刷」します。

import json

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

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

于 2018-12-13T22:38:01.237 に答える
4

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

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

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

于 2018-10-10T05:36:43.863 に答える
3

パンダのデータフレームをjson形式を使用してファイルに書き込もうとしている場合は、これをお勧めします

destination='filepath'
saveFile = open(destination, 'w')
saveFile.write(df.to_json())
saveFile.close()
于 2017-06-03T07:48:30.773 に答える
2

受け入れられた答えは大丈夫です。しかし、それを使用して「jsonシリアル化可能ではありません」というエラーが発生しました。

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

output.write(str(response))

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

于 2018-10-15T04:10:56.743 に答える
2

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)
于 2018-11-01T12:00:47.470 に答える
-2

これは、の使用法に関する追加のヒントですjson.dumps(これは、質問の問題に対する答えではありませんが、numpyデータ型をダンプする必要がある人のためのトリックです):

ディクショナリにNumPyデータ型がありjson.dumps()、追加のパラメータが必要な場合、クレジットはTypeErrorに移動します。タイプ'ndarray'のオブジェクトはJSONシリアル化可能ではなく、次のようなエラーも修正TypeError: Object of type int64 is not JSON serializableされます。

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)

そして、実行します:

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

np.array()の場合は、リストの代わりに文字列を返すこともできます。これは、配列が行に分散されたリストとして出力されるため、大きな配列または多数の配列がある場合に出力が大きくなるためです。警告:ダンプされたディクショナリからアイテムにアクセスして、元の配列として戻すことはより困難です。ただし、配列の文字列だけを使用してもかまわない場合は、辞書が読みやすくなります。次に交換します:

        elif isinstance(obj, (np.ndarray,)):
            return obj.tolist()

と:

        elif isinstance(obj, (np.ndarray,)):
            return str(obj)

あるいは単に:

        else:
            return str(obj)
于 2021-09-13T12:16:53.287 に答える