Reputation: 3967
I have the following code, which is a function to export a transaction history from a digital currency wallet to a json file.
The problems I am facing are two:
I would like to allow the json file to be written in utf-8, as the property 'label' can be utf-8 characters, and if I do not account for that, it will show up in the file as \u\u\u etc. However, no matter what combinations and orderings of encode/decode('utf-8'), I can not get the final output file to print to utf-8.
I would like to order each iteration in the order I wrote them in the code. I tried OrderedDict from collection, but it did not order the items so that Date comes first, etc.
Any help with figuring out how to print this to my file using utf-8 and with the order inside each item as I wrote it.
Thank you very much.
# This line is the last line of a for loop iterating through
# the list of transactions, "for each item in list"
wallet_history.append({"Date": time_string, "TXHash": tx_hash, "Label": label, "Confirmations":
confirmations, "Amount": value_string, "Fee": fee_string, "Balance": balance_string})
try:
history_str = json.dumps(
wallet_history, ensure_ascii=False, sort_keys=False, indent=4)
except TypeError:
QMessageBox.critical(
None, _("Unable to create json"), _("Unable to create json"))
jsonfile.close()
os.remove(fileName)
return
jsonfile.write(history_str)
Upvotes: 0
Views: 197
Reputation: 6387
You need to ensure that both json does not escape characters, and you write your json output as unicode:
import codecs
import json
with codecs.open('tmp.json', 'w', encoding='utf-8') as f:
f.write(json.dumps({u'hello' : u'привет!'}, ensure_ascii=False) + '\n')
$ cat tmp.json
{"hello": "привет!"}
As for your second question: you can use collections.OrderedDict
, but you need to be careful to pass it directly to json.dumps
without changing it to simple dict. See the difference:
from collections import OrderedDict
data = OrderedDict(zip(('first', 'second', 'last'), (1, 10, 3)))
print json.dumps(dict(data)) # {"second": 10, "last": 3, "first": 1}
print json.dumps(data) # {"first": 1, "second": 10, "last": 3}
Upvotes: 2
Reputation: 59604
To make the generated JSON encoded in UTF-8 use ensure_ascii=False
:
Python 2.7.6 (default, Mar 22 2014, 22:59:56)
>>> import json
>>> json.dumps(u'привет!', ensure_ascii=False)
u'"\u043f\u0440\u0438\u0432\u0435\u0442!"'
>>> print json.dumps(u'привет!', ensure_ascii=False)
"привет!"
>>> with open('test', 'w') as f:
... f.write(json.dumps(u'привет!', ensure_ascii=False))
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1-6: ordinal not in range(128)
>>> with open('test', 'w') as f:
... f.write(json.dumps(u'привет!'.encode('utf-8'), ensure_ascii=False))
...
>>> with open('test') as f:
... f.read()
...
'"\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!"'
>>> print '"\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82!"'
"привет!"
>>>
As for the second question about order. It's not possible (except writing you own serializer) or it doesn't make sense: Items in JSON object are out of order using "json.dumps"?
When you pass wallet_history
to json.dumps
it's already lost its order, as it contains dictionaries, which are unordered.
Upvotes: 0