2012-03-06 20 views
15

Tôi đang sử dụng json.dump() và json.load() để lưu/đọc từ điển chuỗi đến/từ đĩa. Vấn đề là tôi không thể có bất kỳ chuỗi nào trong unicode. Họ dường như được unicode không có vấn đề làm thế nào tôi đặt các tham số để dump/tải (bao gồm cả sure_ascii và mã hóa).Bắt buộc mô-đun json Python để làm việc với ASCII

+5

Hãy gửi mã thực tế của bạn và bất kỳ thông báo lỗi bạn đang nhận được. Cảm ơn bạn. – bernie

+0

Ý của bạn là gì trong “Unicode”? Bạn đang nói về việc thoát khỏi các ký tự không phải ASCII để thoát khỏi '\ u1234'? Nếu vậy tại sao mã hóa này không được chấp nhận? Đó là JSON hoàn toàn hợp lệ mà bất kỳ trình phân tích cú pháp nào cũng phải chấp nhận; có các ký tự mà * phải * được mã hóa ở định dạng này ngay cả khi nói chung bạn đang để lại các ký tự không phải ASCII không thoát. – bobince

+1

Vì JSON nguyên bản là định dạng utf-8. Hàm json.loads() của Python chấp nhận các ký hiệu không phải ascii và phân tích chúng thành các chuỗi Unicode. jsob.loads() phân tích tất cả các chuỗi thành kiểu 'unicode' Python, không phải là 'str'. Nhưng json.dumps() thoát ** tất cả các ký hiệu không phải ascii **! Vì vậy, string! = Json.dumps (json.loads (string)) –

Trả lời

20

Nếu bạn chỉ làm việc với các đối tượng JSON đơn giản, bạn có thể sử dụng như sau:

def ascii_encode_dict(data): 
    ascii_encode = lambda x: x.encode('ascii') 
    return dict(map(ascii_encode, pair) for pair in data.items()) 

json.loads(json_data, object_hook=ascii_encode_dict) 

Dưới đây là một ví dụ về cách thức hoạt động:

>>> json_data = '{"foo": "bar", "bar": "baz"}' 
>>> json.loads(json_data)        # old call gives unicode 
{u'foo': u'bar', u'bar': u'baz'} 
>>> json.loads(json_data, object_hook=ascii_encode_dict) # new call gives str 
{'foo': 'bar', 'bar': 'baz'} 

This answer công trình cho một JSON phức tạp hơn cấu trúc và đưa ra một số giải thích tốt đẹp về tham số object_hook. Ngoài ra còn có một câu trả lời ở đó đệ quy có kết quả của một cuộc gọi json.loads() và chuyển đổi tất cả các chuỗi Unicode thành chuỗi byte.

+1

Bạn có thể muốn thay đổi dòng thành 'ascii_encode = lambda x: x.encode (' ascii ',' ignore ') nếu dữ liệu có nhiều ký tự 'ord> 128'. – mac389

+0

Liên kết đến câu trả lời khác cho cấu trúc JSON phức tạp hơn là chính xác những gì tôi cần. – adg

11

Và nếu đối tượng json là một kết hợp của kiểu dữ liệu, không chỉ chuỗi unicode, bạn có thể sử dụng biểu thức này:

def ascii_encode_dict(data): 
    ascii_encode = lambda x: x.encode('ascii') if isinstance(x, unicode) else x 
    return dict(map(ascii_encode, pair) for pair in data.items()) 
Các vấn đề liên quan