Vấn đề rất có thể xảy ra ở đây là json_obj["description"]
thực sự là mã được mã hóa UTF-8 str
, không phải là unicode
. Vì vậy, khi bạn cố gắng write
nó vào một tệp tin codecs
-wrapped, Python phải giải mã nó từ str
thành unicode
để nó có thể mã hóa lại. Và đó là phần không thành công, bởi vì giải mã tự động đó sử dụng sys.getdefaultencoding()
, là 'ascii'
.
Ví dụ:
>>> f = codecs.open('emoji.txt', 'w+', encoding='utf-8')
>>> e = u'\U0001f1ef'
>>> print e
>>> e
u'\U0001f1ef'
>>> f.write(e)
>>> e8 = e.encode('utf-8')
>>> e8
'\xf0\x9f\x87\xaf'
>>> f.write(e8)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 0: ordinal not in range(128)
Có hai giải pháp khả thi ở đây.
Trước tiên, bạn có thể giải mã rõ ràng mọi thứ thành unicode
càng sớm càng tốt. Tôi không chắc chắn nơi của bạn json_obj
là đến từ, nhưng tôi nghi ngờ nó không thực sự là stdlib json.loads
, bởi vì theo mặc định, mà luôn luôn cung cấp cho bạn unicode
khóa và giá trị. Vì vậy, thay thế bất cứ điều gì bạn đang sử dụng cho JSON với các chức năng stdlib có thể sẽ giải quyết vấn đề.
Thứ hai, bạn có thể để mọi thứ dưới dạng đối tượng UTF-8 str
và ở chế độ nhị phân. Nếu bạn biết bạn có UTF-8 ở mọi nơi, chỉ cần open
tệp thay vì codecs.open
và viết mà không cần bất kỳ mã hóa nào.
Ngoài ra, bạn nên cân nhắc sử dụng io.open
thay vì codecs.open
. Nó có một số lợi thế, bao gồm:
- Tăng ngoại lệ thay vì làm sai điều gì nếu bạn vượt qua giá trị không chính xác.
- Thường nhanh hơn.
- Tương thích về phía trước với Python 3.
- Có một số sửa lỗi sẽ không bao giờ được chuyển ngược lại thành
codecs
.
Điểm bất lợi duy nhất là nó không tương thích ngược với Python 2.5. Trừ khi điều đó quan trọng với bạn, đừng sử dụng codecs
.
Là 'json_obj [" description "]' a 'unicode' hoặc' str'? Nếu sau này, mã hóa là gì? Ngoài ra, bạn có thể 'in repr (json_obj [" description "])' ngay trước lỗi, vì vậy chúng ta có thể thấy những gì bạn đang thực sự cố gắng để in? – abarnert
Ngoài ra, 'json_obj' đến từ đâu? Tên này ngụ ý mô-đun 'json' stdlib, nhưng thực tế là các khóa và giá trị rõ ràng là' str' ngụ ý rằng nó không phải… – abarnert