Chuyển đổi từ điển Python sang mảng JSON


98

Hiện tại tôi có từ điển này, được in bằng 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}

Khi tôi làm điều này:

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

Tôi gặp lỗi này: 'utf8' codec can't decode byte 0xff in position 0: invalid start byte


Vấn đề của bạn nằm ở đây:\xff
Benjamin Toueg

Câu trả lời:


167

Nếu bạn thấy tốt với các ký hiệu không in được trong json của mình, thì hãy thêm ensure_ascii=Falsevào dumpslệnh gọi.

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

Nếu ensure_asciilà false, thì giá trị trả về sẽ là một unicodeđối tượng dụ để Python bình thường strđể unicode quy định ép buộc thay vì được trốn thoát đến một ASCII str.


1
thêm indent=nvào các tùy chọn để in đẹp, nơi nlà số không gian để thụt lề
RTF

17

ensure_ascii = False thực sự chỉ giải mã vấn đề ở giai đoạn giải mã:

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

Cuối cùng, bạn không thể lưu trữ các byte thô trong tài liệu JSON, vì vậy bạn sẽ muốn sử dụng một số phương tiện mã hóa rõ ràng một chuỗi các byte tùy ý dưới dạng chuỗi ASCII - chẳng hạn như 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'}

Bạn có thể chuyển dữ liệu nhị phân tùy ý (không hiệu quả) trong json bằng cách sử dụng mã hóa 'latin1'
jfs 02/02

1
Tôi cho rằng bạn có thể, nhưng json được thiết kế / dự định sử dụng utf-8.
Karl Knechtel

2
@JFSebastian: Thật vậy, rất kém hiệu quả so với b64encode. Ví dụ, đối với chuỗi 256 nhân vật s = ''.join(chr(i) for i in xrange(256)), len(json.dumps(b64encode(s))) == 346vs len(json.dumps(s.decode('latin1'))) == 1045.
martineau

10

Nếu bạn sử dụng Python 2, đừng quên thêm nhận xét mã hóa tệp UTF-8 vào dòng đầu tiên của tập lệnh của bạn.

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

Điều này sẽ khắc phục một số sự cố Unicode và giúp cuộc sống của bạn dễ dàng hơn.


2

Một giải pháp khả thi mà tôi sử dụng là sử dụng python3. Nó dường như giải quyết nhiều vấn đề utf.

Xin lỗi vì câu trả lời muộn, nhưng nó có thể giúp ích cho mọi người trong tương lai.

Ví dụ,

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

4
Chắc chắn rồi, bạn nói đúng, Python 3 đã giải quyết được nhiều vấn đề về mã hóa. Nhưng đó không phải là câu trả lời cho câu hỏi đó. Nó được gắn thẻ rõ ràng bằng python-2.7. Vì vậy, những gì bạn đang nói là một cái gì đó như sau: Không có máy hút bụi tích hợp trong chiếc xe cũ của bạn. Vì vậy, hãy mua một chiếc xe mới thay vì lắp thêm một máy hút bụi trên chiếc xe cũ của bạn.
colidyre
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.