折腾:
期间,已经用:
【已解决】python中把dict的json输出到文件且带缩进和不要unicode的\uxxxx
可以输出要的json的内容:
<code>{ "description": "总结之前使用过有道云笔记和有道云协作的心得供参考", "links": { "sidebar": { "主页": "https://www.crifan.com" } }, "author": "Crifan Li <[email protected]>", "title": "有道云笔记和云协作使用总结", "gitbook": "3.2.3", "language": "zh-hans", "plugins": [ "theme-comscore", "-lunr", "-search", "search-plus", "disqus", "-highlight", "prism", "prism-themes", "github-buttons", "splitter", "-sharing", "sharing-plus", "tbfed-pagefooter", "expandable-chapters-small", "ga", "donate", "sitemap-general", "copy-code-button", "-alerts", "-bootstrap-callout", "callouts", "toolbar-button" ], "pluginsConfig": { "toolbar-button": { "url": "http://book.crifan.com/books/youdao_note_summary/pdf/youdao_note_summary.pdf", "icon": "fa-file-pdf-o", "label": "下载PDF" }, "sitemap-general": { "prefix": "https://book.crifan.com/gitbook/youdao_note_summary/website/" }, "sharing": { "qq": true, "douban": false, "all": [ "douban", "facebook", "google", "instapaper", "line", "linkedin", "messenger", "pocket", "qq", "qzone", "stumbleupon", "twitter", "viber", "vk", "weibo", "whatsapp" ], "google": false, "stumbleupon": false, "hatenaBookmark": false, "twitter": true, "vk": false, "linkedin": false, "instapaper": false, "pocket": false, "weibo": true, "viber": false, "facebook": true, "qzone": false, "messenger": false, "line": false, "whatsapp": false }, "tbfed-pagefooter": { "modify_format": "YYYY-MM-DD HH:mm:ss", "modify_label": "该文件修订时间:", "copyright": "crifan.com,使用<a href='https://creativecommons.org/licenses/by-sa/4.0/deed.zh'>知识署名-相同方式共享4.0协议</a>发布" }, "github-buttons": { "buttons": [ { "repo": "youdao_note_summary", "count": true, "type": "star", "user": "crifan", "size": "small" }, { "count": false, "width": "120", "type": "follow", "user": "crifan", "size": "small" } ] }, "disqus": { "shortName": "crifan" }, "prism": { "css": [ "prism-themes/themes/prism-atom-dark.css" ] }, "ga": { "token": "UA-28297199-1" }, "theme-default": { "showLevel": true }, "donate": { "alipay": "https://www.crifan.com/files/res/crifan_com/crifan_alipay_pay.jpg", "title": "", "alipayText": "支付宝打赏给Crifan", "button": "打赏", "wechatText": "微信打赏给Crifan", "wechat": "https://www.crifan.com/files/res/crifan_com/crifan_wechat_pay.jpg" }, "callouts": { "showTypeInHeader": false } }, "root": "./src" } </code>
了,但是和原先希望的字段的顺序,有点不一样:
<code>{ "title": "有道云笔记和云协作使用总结", "description": "总结之前使用过有道云笔记和有道云协作的心得供参考", "author": "Crifan Li <[email protected]>", "language": "zh-hans", "gitbook": "3.2.3", "root": "./src", "links": { "sidebar": { "主页": "https://www.crifan.com" } }, "plugins": [ "theme-comscore", "-lunr", "-search", "search-plus", "disqus", "-highlight", "prism", "prism-themes", "github-buttons", "splitter", "-sharing", "sharing-plus", "tbfed-pagefooter", "expandable-chapters-small", "ga", "donate", "sitemap-general", "copy-code-button", "-alerts", "-bootstrap-callout", "callouts", "toolbar-button" ], "pluginsConfig": { "callouts": { "showTypeInHeader": false }, "theme-default": { "showLevel": true }, "disqus": { "shortName": "crifan" }, "prism": { "css": [ "prism-themes/themes/prism-atom-dark.css" ] }, "github-buttons": { "buttons": [ { "user": "crifan", "repo": "youdao_note_summary", "type": "star", "count": true, "size": "small" }, { "user": "crifan", "type": "follow", "width": "120", "count": false, "size": "small" } ] }, "sharing": { "douban": false, "facebook": true, "google": false, "hatenaBookmark": false, "instapaper": false, "line": false, "linkedin": false, "messenger": false, "pocket": false, "qq": true, "qzone": false, "stumbleupon": false, "twitter": true, "viber": false, "vk": false, "weibo": true, "whatsapp": false, "all": [ "douban", "facebook", "google", "instapaper", "line", "linkedin", "messenger", "pocket", "qq", "qzone", "stumbleupon", "twitter", "viber", "vk", "weibo", "whatsapp" ] }, "tbfed-pagefooter": { "copyright": "crifan.com,使用<a href='https://creativecommons.org/licenses/by-sa/4.0/deed.zh'>知识署名-相同方式共享4.0协议</a>发布", "modify_label": "该文件修订时间:", "modify_format": "YYYY-MM-DD HH:mm:ss" }, "ga": { "token": "UA-28297199-1" }, "donate": { "wechat": "https://www.crifan.com/files/res/crifan_com/crifan_wechat_pay.jpg", "alipay": "https://www.crifan.com/files/res/crifan_com/crifan_alipay_pay.jpg", "title": "", "button": "打赏", "alipayText": "支付宝打赏给Crifan", "wechatText": "微信打赏给Crifan" }, "sitemap-general": { "prefix": "https://book.crifan.com/gitbook/youdao_note_summary/website/" }, "toolbar-button": { "icon": "fa-file-pdf-o", "label": "下载PDF", "url": "http://book.crifan.com/books/youdao_note_summary/pdf/youdao_note_summary.pdf" } } } </code>
希望此处,可以把:
“root”: “./src”
等字段,能输出在文件的最开始
python json dump key order
python – Items in JSON object are out of order using “json.dumps”? – Stack Overflow
去试试
OrderedDict
或sort_keys=True
Issue 6105: json.dumps doesn’t respect OrderedDict’s iteration order – Python tracker
18.2. json — JSON encoder and decoder — Python 2.7.15 documentation
“If sort_keys is true (default: False), then the output of dictionaries will be sorted by key.”
<code>json.dump(jsonDict, outputFp, indent=indent, ensure_ascii=False, sort_keys=True) </code>
结果
先root再title,是根据字母排序了。但是不是我要的效果。
<code>from collections import OrderedDict json.dump(OrderedDict(jsonDict), outputFp, indent=indent, ensure_ascii=False) </code>
结果和之前顺序一样,没变化
感觉是:
此处需要:
json文件,去load加载进来时,就要保持order 顺序才行
然后dump输出时,才能用OrderedDict去保持原先顺序的
而load时,此处不知道如何才能保持
python – Can I get JSON to load into an OrderedDict? – Stack Overflow
是我要找的
【总结】
但是弄了半天,其实是已经通过:
<code> import os import json from pprint import pprint import sys import copy import codecs from collections import OrderedDict templateJson = {} currentJson = {} currPath = os.getcwd() print("currPath=%s" % currPath) bookJsonTemplateFullPath = os.path.join(currPath, BookJsonTemplateFilename) print("bookJsonTemplateFullPath=%s" % bookJsonTemplateFullPath) # /Users/crifan/GitBook/Library/Import/book_common.json with open(bookJsonTemplateFullPath) as templateJsonFp: # templateJson = json.load(templateJsonFp, encoding="utf-8") templateJson = json.load(templateJsonFp, encoding="utf-8", object_pairs_hook=OrderedDict) # templateJson = OrderedDict(templateJson) # print("type(templateJson)=%s" % (type(templateJson))) #type(templateJson)=<class 'collections.OrderedDict'> bookJsonCurrentFullPath = os.path.join(currPath, CurrentGitbookName, BookJsonCurrentFilename) print("bookJsonCurrentFullPath=%s" % bookJsonCurrentFullPath) with open(bookJsonCurrentFullPath) as currentJsonFp: # currentJson = json.load(currentJsonFp, encoding="utf-8") currentJson = json.load(currentJsonFp, encoding="utf-8", object_pairs_hook=OrderedDict) # currentJson = OrderedDict(currentJson) bookJsonFullPath = os.path.join(currPath, CurrentGitbookName, BookJsonOutputFilename) print("bookJsonFullPath=%s" % bookJsonFullPath) saveJsonToFile(templateJson, bookJsonFullPath) </code>
是可以在加载之前json文件,并保留字段顺序的
且也可以输出对应的OrderedDict到文件中,也保留了之前的顺序
但是由于此处中间使用了:
<code> def recursiveMergeDict(aDict, bDict): """ Recursively merge dict a to b, return merged dict b Note: Sub dict and sub list's won't be overwritten but also updated/merged example: (1) input and output example: input: { "keyStr": "strValueA", "keyInt": 1, "keyBool": true, "keyList": [ { "index0Item1": "index0Item1", "index0Item2": "index0Item2" }, { "index1Item1": "index1Item1" }, { "index2Item1": "index2Item1" } ] } and { "keyStr": "strValueB", "keyInt": 2, "keyList": [ { "index0Item1": "index0Item1_b" }, { "index1Item1": "index1Item1_b" } ] } output: { "keyStr": "strValueB", "keyBool": true, "keyInt": 2, "keyList": [ { "index0Item1": "index0Item1_b", "index0Item2": "index0Item2" }, { "index1Item1": "index1Item1_b" }, { "index2Item1": "index2Item1" } ] } (2) code usage example: import copy cDict = recursiveMergeDict(aDict, copy.deepcopy(bDict)) Note: bDict should use deepcopy, otherwise will be altered after call this function !!! """ aDictItems = None if (sys.version_info[0] == 2): # is python 2 aDictItems = aDict.iteritems() else: # is python 3 aDictItems = aDict.items() for aKey, aValue in aDictItems: # print("------ [%s]=%s" % (aKey, aValue)) if aKey not in bDict: bDict[aKey] = aValue else: bValue = bDict[aKey] # print("aValue=%s" % aValue) # print("bValue=%s" % bValue) if isinstance(aValue, dict): recursiveMergeDict(aValue, bValue) elif isinstance(aValue, list): aValueListLen = len(aValue) bValueListLen = len(bValue) bValueListMaxIdx = bValueListLen - 1 for aListIdx in range(aValueListLen): # print("---[%d]" % aListIdx) aListItem = aValue[aListIdx] # print("aListItem=%s" % aListItem) if aListIdx <= bValueListMaxIdx: bListItem = bValue[aListIdx] # print("bListItem=%s" % bListItem) recursiveMergeDict(aListItem, bListItem) else: # print("bDict=%s" % bDict) # print("aKey=%s" % aKey) # print("aListItem=%s" % aListItem) bDict[aKey].append(aListItem) return bDict pprint("/"*80) bookJson = recursiveMergeDict(templateJson, copy.deepcopy(currentJson)) </code>
导致两个json:
templateJson和currentJson
被合并之后,结果输出的字段的顺序,虽然也是OrderedDict,但却不是我们要的效果了。
只能输出这样的结果:
<code>{ "title": "有道云笔记和云协作使用总结", "description": "总结之前使用过有道云笔记和有道云协作的心得供参考", "pluginsConfig": { "github-buttons": { "buttons": [ { "repo": "youdao_note_summary", "user": "crifan", "type": "star", "count": true, "size": "small" }, { "user": "crifan", "type": "follow", "width": "120", "count": false, "size": "small" } ] }, "sitemap-general": { "prefix": "https://book.crifan.com/gitbook/youdao_note_summary/website/" }, "toolbar-button": { "url": "http://book.crifan.com/books/youdao_note_summary/pdf/youdao_note_summary.pdf", "icon": "fa-file-pdf-o", "label": "下载PDF" }, "callouts": { "showTypeInHeader": false }, "theme-default": { "showLevel": true }, "disqus": { "shortName": "crifan" }, "prism": { "css": [ "prism-themes/themes/prism-atom-dark.css" ] }, "sharing": { "douban": false, "facebook": true, "google": false, "hatenaBookmark": false, "instapaper": false, "line": false, "linkedin": false, "messenger": false, "pocket": false, "qq": true, "qzone": false, "stumbleupon": false, "twitter": true, "viber": false, "vk": false, "weibo": true, "whatsapp": false, "all": [ "douban", "facebook", "google", "instapaper", "line", "linkedin", "messenger", "pocket", "qq", "qzone", "stumbleupon", "twitter", "viber", "vk", "weibo", "whatsapp" ] }, "tbfed-pagefooter": { "copyright": "crifan.com,使用<a href='https://creativecommons.org/licenses/by-sa/4.0/deed.zh'>知识署名-相同方式共享4.0协议</a>发布", "modify_label": "该文件修订时间:", "modify_format": "YYYY-MM-DD HH:mm:ss" }, "ga": { "token": "UA-28297199-1" }, "donate": { "wechat": "https://www.crifan.com/files/res/crifan_com/crifan_wechat_pay.jpg", "alipay": "https://www.crifan.com/files/res/crifan_com/crifan_alipay_pay.jpg", "title": "", "button": "打赏", "alipayText": "支付宝打赏给Crifan", "wechatText": "微信打赏给Crifan" } }, "author": "Crifan Li <[email protected]>", "language": "zh-hans", "gitbook": "3.2.3", "root": "./src", "links": { "sidebar": { "主页": "https://www.crifan.com" } }, "plugins": [ "theme-comscore", "-lunr", "-search", "search-plus", "disqus", "-highlight", "prism", "prism-themes", "github-buttons", "splitter", "-sharing", "sharing-plus", "tbfed-pagefooter", "expandable-chapters-small", "ga", "donate", "sitemap-general", "copy-code-button", "-alerts", "-bootstrap-callout", "callouts", "toolbar-button" ] } </code>
虽然:
“root”: “./src”,
没有像之前无序输出时被放到最后,但是
<code> "author": "Crifan Li <[email protected]>", "language": "zh-hans", "gitbook": "3.2.3", "root": "./src", "links": { "sidebar": { "主页": "https://www.crifan.com" } }, </code>
这部分,被放到中间了。还不是自己希望的,放在开头的位置的效果。