Konvertieren Sie das Python-Wörterbuch in ein JSON-Array


98

Derzeit habe ich dieses Wörterbuch, gedruckt mit pprint:

{'AlarmExTempHum': '\x00\x00\x00\x00\x00\x00\x00\x00',  
'AlarmIn': 0,  
'AlarmOut': '\x00\x00',  
'AlarmRain': 0,  
'AlarmSoilLeaf': '\x00\x00\x00\x00',  
'BarTrend': 60,  
'BatteryStatus': 0,  
'BatteryVolts': 4.751953125,  
'CRC': 55003,
'EOL': '\n\r',
'ETDay': 0,
'ETMonth': 0,
'ETYear': 0,
'ExtraHum1': None,
'ExtraHum2': None,
'ExtraHum3': None,
'ExtraHum4': None,
'ExtraHum5': None,
'ExtraHum6': None,
'ExtraHum7': None,
'ExtraTemp1': None,
'ExtraTemp2': None,
'ExtraTemp3': None,
'ExtraTemp4': None,
'ExtraTemp5': None,
'ExtraTemp6': None,
'ExtraTemp7': None,
'ForecastIcon': 2,
'ForecastRuleNo': 122,
'HumIn': 31,
'HumOut': 94,
'LOO': 'LOO',
'LeafTemps': '\xff\xff\xff\xff',
'LeafWetness': '\xff\xff\xff\x00',
'NextRec': 37,
'PacketType': 0,
'Pressure': 995.9363359295631,
'RainDay': 0.0,
'RainMonth': 0.0,
'RainRate': 0.0,
'RainStorm': 0.0,
'RainYear': 2.8,
'SoilMoist': '\xff\xff\xff\xff',
'SoilTemps': '\xff\xff\xff\xff',
'SolarRad': None,
'StormStartDate': '2127-15-31',
'SunRise': 849,
'SunSet': 1611,
'TempIn': 21.38888888888889,
'TempOut': 0.8888888888888897,
'UV': None,
'WindDir': 219,
'WindSpeed': 3.6,
'WindSpeed10Min': 3.6}

Wenn ich das mache:

import json
d = (my dictionary above)
jsonarray = json.dumps(d)

Ich erhalte diesen Fehler: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte


Ihr Problem liegt hier:\xff
Benjamin Toueg

Antworten:


167

Wenn Sie mit nicht druckbaren Symbolen in Ihrem JSON gut zurechtkommen, fügen Sie ensure_ascii=Falsezum dumpsAnruf hinzu.

>>> json.dumps(your_data, ensure_ascii=False)

Wenn ensure_asciifalsch ist, dann wird der Rückgabewert sein , unicodezB unter normalen Python strzu unicode Zwang Regeln statt in eine ASCII entkommen ist str.


1
Fügen Sie indent=nzu den Optionen hinzu, um hübsch zu drucken, wo nist die Anzahl der einzurückenden Leerzeichen
RTF

17

sure_ascii = False verschiebt das Problem wirklich nur auf die Dekodierungsphase:

>>> dict2 = {'LeafTemps': '\xff\xff\xff\xff',}
>>> json1 = json.dumps(dict2, ensure_ascii=False)
>>> print(json1)
{"LeafTemps": "����"}
>>> json.loads(json1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/json/__init__.py", line 328, in loads
    return _default_decoder.decode(s)
  File "/usr/lib/python2.7/json/decoder.py", line 365, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/lib/python2.7/json/decoder.py", line 381, in raw_decode
    obj, end = self.scan_once(s, idx)
UnicodeDecodeError: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte

Letztendlich können Sie keine Rohbytes in einem JSON-Dokument speichern. Daher sollten Sie eine Methode verwenden, um eine Folge beliebiger Bytes eindeutig als ASCII-Zeichenfolge zu codieren, z. B. base64.

>>> import json
>>> from base64 import b64encode, b64decode
>>> my_dict = {'LeafTemps': '\xff\xff\xff\xff',} 
>>> my_dict['LeafTemps'] = b64encode(my_dict['LeafTemps'])
>>> json.dumps(my_dict)
'{"LeafTemps": "/////w=="}'
>>> json.loads(json.dumps(my_dict))
{u'LeafTemps': u'/////w=='}
>>> new_dict = json.loads(json.dumps(my_dict))
>>> new_dict['LeafTemps'] = b64decode(new_dict['LeafTemps'])
>>> print new_dict
{u'LeafTemps': '\xff\xff\xff\xff'}

Sie könnten beliebige Binärdaten (ineffizient) in json mit der 'latin1'-Codierung übergeben
jfs

1
Sie könnten, nehme ich an, aber json ist für die Verwendung von utf-8 konzipiert / vorgesehen.
Karl Knechtel

2
@JFSebastian: In der Tat sehr ineffizient im Vergleich zu b64encode. Zum Beispiel für die 256 Zeichenkette s = ''.join(chr(i) for i in xrange(256)), len(json.dumps(b64encode(s))) == 346vs len(json.dumps(s.decode('latin1'))) == 1045.
Martineau

10

Wenn Sie Python 2 verwenden, vergessen Sie nicht, den Kommentar zur UTF-8-Dateikodierung in die erste Zeile Ihres Skripts einzufügen.

# -*- coding: UTF-8 -*-

Dies wird einige Unicode-Probleme beheben und Ihnen das Leben erleichtern.


2

Eine mögliche Lösung, die ich verwende, ist die Verwendung von Python3. Es scheint viele utf-Probleme zu lösen.

Entschuldigen Sie die späte Antwort, aber sie kann den Menschen in Zukunft helfen.

Beispielsweise,

#!/usr/bin/env python3
import json
# your code follows

4
Sicher, Sie haben verdammt Recht, Python 3 hat viele Codierungsprobleme gelöst. Aber das ist nicht die Antwort auf diese Frage. Es ist explizit mit Python-2.7 gekennzeichnet. Was Sie also sagen, ist ungefähr so: In Ihrem alten Auto ist kein Staubsauger eingebaut. Kaufen Sie also bitte ein neues Auto, anstatt Ihrem alten Auto einen Staubsauger hinzuzufügen.
Colidyre
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.