2010-05-05 44 views
46

Tôi gặp sự cố với JSON trong python.Phân loại đầu ra JSON bằng Python

Trong thực tế, nếu tôi cố gắng thực thi mã này, python cho tôi chuỗi JSON được sắp xếp!

Ví dụ:

values = {'profile' : 'testprofile', 
      'format': 'RSA_RC4_Sealed', 
      'enc_key' : base64.b64encode(chiave_da_inviare), 
      'request' : base64.b64encode(data) 
     } 


values_json = json.dumps(values, sort_keys=False, separators=(',', ':')) 

và đây là kết quả:

{"profile":"testprofile","enc_key":"GBWo[...]NV6w==","request":"TFl[...]uYw==","format":"RSA_RC4_Sealed"} 

Như bạn thấy đấy, tôi đã cố gắng để sử dụng "sort_keys = False" nhưng không có gì thay đổi.

Làm cách nào để ngăn chặn việc phân loại các chuỗi JSON của tôi?

Trả lời

43

Bạn đang lưu trữ giá trị của mình vào một trăn dict không có khái niệm vốn có của trật tự nào cả, nó chỉ là một bản đồ giá trị => key. Vì vậy, các mục của bạn sẽ mất tất cả thứ tự khi bạn đặt chúng vào biến "giá trị".

Trong thực tế, cách duy nhất để có được một thứ tự xác định sẽ là sử dụng "sort_keys = True", mà tôi giả định đặt chúng trong thứ tự chữ và số. Tại sao thứ tự lại quan trọng như vậy?

+0

vì tôi cho rằng mã của tôi không hoạt động do thứ tự không đúng. là nó có thể? – elledienne

+7

Mã của bạn đang hoạt động tốt, chỉ là lệnh đó không được xác định. Nếu bạn muốn luôn luôn được sử dụng nhất quán "sort_keys = True". –

+0

cảm ơn! Tôi đã giải quyết !! bạn đá;) – elledienne

4

Các phím không được sắp xếp: "hồ sơ", "enc_key", "yêu cầu", "định dạng". Có vẻ như bạn muốn chúng xuất hiện theo cùng một thứ tự mà bạn đã tạo chúng trong từ điển, nhưng từ điển vốn đã không được phân loại, chúng không nhớ thứ tự bạn đã chèn vào.

Có một số triển khai SortedDict mà bạn có thể sử dụng, nhưng bộ mã hóa json sẽ không biết sử dụng nó để lấy các khóa theo thứ tự bạn muốn.

6

Nếu bạn chỉ định sort_keys=False thì Python sẽ chỉ in các mục theo thứ tự bất kỳ mà chúng xuất hiện trong đối tượng dict Python nằm bên dưới. Trong một số trường hợp, điều này có thể xảy ra giống với thứ tự sắp xếp theo thứ tự chữ và số mặc định. Trong ví dụ của bạn, các phím AREN'T thậm chí được sắp xếp như vậy, vì "định dạng" xuất hiện sau "yêu cầu". Bất kể, tham số sort_keys vẫn còn hiệu lực, bằng chứng là mẫu mã này:

>>> import json 
>>> json.dumps({"a":5, "b":6, "c":7}, sort_keys=False) 
'{"a": 5, "c": 7, "b": 6}' 
82

Hãy thử OrderedDict từ thư viện chuẩn collections:

>>> import json 
>>> from collections import OrderedDict 
>>> values = OrderedDict([('profile','testprofile'), 
          ('format', 'RSA_RC4_Sealed'), 
          ('enc_key', '...'), 
          ('request', '...')]) 
>>> json.dumps(values, sort_keys=False) 
'{"profile": "testprofile", "format": "RSA_RC4_Sealed", "enc_key": "...", "request": "..."}' 

Đáng tiếc là tính năng này là New in version 2.7 cho collections

+4

+1 để cung cấp câu trả lời đơn giản nhưng trực tiếp cho câu hỏi được hỏi – mloskot

+0

Tính năng này có sẵn cho phiên bản cũ hơn của Python bằng cách sử dụng 'pip install ordereddict' và sau đó thay đổi dòng nhập thành' từ orderdict import OrderedDict' như đã nêu trên [this answer] (http://stackoverflow.com/a/6852800/892951) (được thử nghiệm trên Python 2.6.6). – chirale

+0

Nice ... nhưng lưu ý, đáng ngạc nhiên, trong khi điều này làm việc cho json 2.0.9 nó không hoạt động (tức là thứ tự không được bảo quản trong serialization) với simplejson 2.0.9 (đó được cho là chỉ là phiên bản cài đặt bên ngoài của json ?!) . Phiên bản Python là 2.7.3. –

9

Một OrderedDict như được thảo luận ở nơi khác là hầu hết các giải pháp cho vấn đề của bạn, và một 'ObjDict' có thể còn tốt hơn.

Tuy nhiên nếu bạn cần thứ tự được duy trì khi tải, thì bạn cũng sẽ cần json.loads() để tải các giá trị vào một OrderedDict. Để thực hiện việc này, hãy sử dụng

from collections import OrderedDict 
values=json.loads(jsontext,object_pairs_hook=OrderedDict) 

Nếu không, ngay cả khi tệp json sẽ theo thứ tự, thứ tự đó sẽ bị mất khi được tải.

Có lẽ giải pháp tốt hơn nữa là sử dụng 'ObjDict' thay cho OrderedDict. Điều này đòi hỏi một cài đặt pip objdict. ObjDict vẫn duy trì thứ tự, như với OrderedDict, nhưng cũng mang lại sự hỗ trợ JSON và xử lý tốt hơn ví dụ này.

from objdict import ObjDict 
values = ObjDict("""{"profile" : "testprofile", 
     "format": "RSA_RC4_Sealed" }""") 
values.enc_key = base64.b64encode(chiave_da_inviare) 
values.request = base64.b64encode(data) 

values_json = values.dumps(separators=(',', ':')) 
Các vấn đề liên quan