948 Stimmen

Speichern von UTF-8-Texten mit json.dumps als UTF-8, nicht als \u Escape-Sequenz

Beispielcode (in einem REPL):

import json
json_string = json.dumps(" ")
print(json_string)

Ausgabe:

"\u05d1\u05e8\u05d9 \u05e6\u05e7\u05dc\u05d4"

Das Problem: Es ist nicht menschenlesbar. Meine (intelligenten) Benutzer möchten möglicherweise Textdateien mit JSON-Dumps überprüfen oder sogar bearbeiten (und ich würde lieber kein XML verwenden).

Gibt es eine Möglichkeit, Objekte in UTF-8 JSON-Strings zu serialisieren (anstatt \uXXXX)?

32voto

Jonathan Ray Punkte 529

Pieters' Python 2 Workaround scheitert an einem Grenzfall:

d = {u'Schlüsselwort': u'Schlechte Kreditkarten'}
with io.open('dateiname', 'w', encoding='utf8') as json_datei:
    daten = json.dumps(d, ensure_ascii=False).decode('utf8')
    try:
        json_datei.write(data)
    except TypeError:
        # Dekodieren der Daten zuerst in Unicode
        json_datei.write(data.decode('utf8'))

UnicodeEncodeError: 'ascii' codec kann Zeichen u'\xe7' in Position 25 nicht codieren: Ordinal nicht im Bereich von 128

Es stürzte auf den .decode('utf8') Teil von Zeile 3 ab. Ich habe das Problem behoben, indem ich das Programm viel einfacher gemacht habe, indem ich diesen Schritt sowie die Sonderbehandlung von ASCII vermieden habe:

with io.open('dateiname', 'w', encoding='utf8') as json_datei:
  daten = json.dumps(d, ensure_ascii=False, encoding='utf8')
  json_datei.write(unicode(data))

cat dateiname
{"Schlüsselwort": "Schlechte Kreditkarten"}

13voto

ChrisXiao Punkte 91

Verwenden Sie unicode-escape, um das Problem zu lösen

>>>import json
>>>json_string = json.dumps(" ")
>>>json_string.encode('ascii').decode('unicode-escape')
'" "'

Erklärung

>>>s = '    '
>>>print('Unicode: ' + s.encode('unicode-escape').decode('utf-8'))

Unicode: \u6f22  \u03c7\u03b1\u03bd  \u0445\u0430\u043d

>>>u = s.encode('unicode-escape').decode('utf-8')
>>>print('Original: ' + u.encode("utf-8").decode('unicode-escape'))

Original:     

Ursprüngliche QuellePython3 unicode-escape unicode 16

9voto

Chandan Sharma Punkte 1824

Wenn Sie einen JSON-String aus einer Datei laden und der Dateiinhalt arabische Texte enthält, funktioniert dies.

Angenommen, es gibt eine Datei namens arabic.json

{
  "key1": "",
  "key2": " "
}

Holen Sie sich die arabischen Inhalte aus der Datei arabic.json

with open(arabic.json, encoding='utf-8') as f:
   # Deserialisiert es
   json_data = json.load(f)
   f.close()

# JSON formatierter String
json_data2 = json.dumps(json_data, ensure_ascii = False)

Um JSON-Daten in einem Django-Template zu verwenden, befolgen Sie die unten stehenden Schritte:

# Wenn der JSON-Index in einer Django-Template-Datei abgerufen werden muss, decodieren Sie einfach den codierten String.

json.JSONDecoder().decode(json_data2)

Fertig! Jetzt können wir die Ergebnisse als JSON-Index mit arabischen Werten erhalten.

8voto

Cheney Punkte 890

Das Folgende ist mein Verständnis der obigen Leseantwort und Google.

# coding:utf-8
r"""
@update: 2017-01-09 14:44:39
@explain: str, unicode, bytes in python2to3
    #python2 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 7: ordinal not in range(128)
    #1.reload
    #importlib,sys
    #importlib.reload(sys)
    #sys.setdefaultencoding('utf-8') #python3 don't have this attribute.
    #not suggest even in python2 #see:http://stackoverflow.com/questions/3828723/why-should-we-not-use-sys-setdefaultencodingutf-8-in-a-py-script
    #2.overwrite /usr/lib/python2.7/sitecustomize.py or (sitecustomize.py and PYTHONPATH=".:$PYTHONPATH" python)
    #too complex
    #3.control by your own (best)
    #==> all string must be unicode like python3 (u'xx'|b'xx'.encode('utf-8')) (unicode 's disappeared in python3)
    #see: http://blog.ernest.me/post/python-setdefaultencoding-unicode-bytes

    #how to Saving utf-8 texts in json.dumps as UTF8, not as \u escape sequence
    #http://stackoverflow.com/questions/18337407/saving-utf-8-texts-in-json-dumps-as-utf8-not-as-u-escape-sequence
"""

from __future__ import print_function
import json

a = {"b": u""}  # füge u für die Python2-Kompatibilität hinzu
print('%r' % a)
print('%r' % json.dumps(a))
print('%r' % (json.dumps(a).encode('utf8')))
a = {"b": u""}
print('%r' % json.dumps(a, ensure_ascii=False))
print('%r' % (json.dumps(a, ensure_ascii=False).encode('utf8')))
# print(a.encode('utf8')) #AttributeError: 'dict' object has no attribute 'encode'
print('')

# python2:bytes=str; python3:bytes
b = a['b'].encode('utf-8')
print('%r' % b)
print('%r' % b.decode("utf-8"))
print('')

# python2:unicode; python3:str=unicode
c = b.decode('utf-8')
print('%r' % c)
print('%r' % c.encode('utf-8'))
"""
#python2
{'b': u'\u4e2d\u6587'}
'{"b": "\\u4e2d\\u6587"}'
'{"b": "\\u4e2d\\u6587"}'
u'{"b": "\u4e2d\u6587"}'
'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

'\xe4\xb8\xad\xe6\x96\x87'
u'\u4e2d\u6587'

u'\u4e2d\u6587'
'\xe4\xb8\xad\xe6\x96\x87'

#python3
{'b': ''}
'{"b": "\\u4e2d\\u6587"}'
b'{"b": "\\u4e2d\\u6587"}'
'{"b": ""}'
b'{"b": "\xe4\xb8\xad\xe6\x96\x87"}'

b'\xe4\xb8\xad\xe6\x96\x87'
''

''
b'\xe4\xb8\xad\xe6\x96\x87'
"""

6voto

Neit Sabes Punkte 61

Hier ist meine Lösung mit json.dump():

def jsonWrite(p, pyobj, ensure_ascii=False, encoding=SYSTEM_ENCODING, **kwargs):
    with codecs.open(p, 'wb', 'utf_8') as fileobj:
        json.dump(pyobj, fileobj, ensure_ascii=ensure_ascii,encoding=encoding, **kwargs)

wo SYSTEM_ENCODING auf:

locale.setlocale(locale.LC_ALL, '')
SYSTEM_ENCODING = locale.getlocale()[1]

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X