折腾:
期间,已经用:
【已解决】python中把dict的json输出到文件且带缩进和不要unicode的\uxxxx
可以输出要的json的内容:
<code>{
"description": "总结之前使用过有道云笔记和有道云协作的心得供参考",
"links": {
"sidebar": {
"主页": "https://www.crifan.org"
}
},
"author": "Crifan Li <admin@crifan.org>",
"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.org/books/youdao_note_summary/pdf/youdao_note_summary.pdf",
"icon": "fa-file-pdf-o",
"label": "下载PDF"
},
"sitemap-general": {
"prefix": "https://book.crifan.org/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.org,使用<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.org/files/res/crifan_com/crifan_alipay_pay.jpg",
"title": "",
"alipayText": "支付宝打赏给Crifan",
"button": "打赏",
"wechatText": "微信打赏给Crifan",
"wechat": "https://www.crifan.org/files/res/crifan_com/crifan_wechat_pay.jpg"
},
"callouts": {
"showTypeInHeader": false
}
},
"root": "./src"
}
</code>了,但是和原先希望的字段的顺序,有点不一样:
<code>{
"title": "有道云笔记和云协作使用总结",
"description": "总结之前使用过有道云笔记和有道云协作的心得供参考",
"author": "Crifan Li <admin@crifan.org>",
"language": "zh-hans",
"gitbook": "3.2.3",
"root": "./src",
"links": {
"sidebar": {
"主页": "https://www.crifan.org"
}
},
"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.org,使用<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.org/files/res/crifan_com/crifan_wechat_pay.jpg",
"alipay": "https://www.crifan.org/files/res/crifan_com/crifan_alipay_pay.jpg",
"title": "",
"button": "打赏",
"alipayText": "支付宝打赏给Crifan",
"wechatText": "微信打赏给Crifan"
},
"sitemap-general": {
"prefix": "https://book.crifan.org/gitbook/youdao_note_summary/website/"
},
"toolbar-button": {
"icon": "fa-file-pdf-o",
"label": "下载PDF",
"url": "http://book.crifan.org/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.org/gitbook/youdao_note_summary/website/"
},
"toolbar-button": {
"url": "http://book.crifan.org/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.org,使用<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.org/files/res/crifan_com/crifan_wechat_pay.jpg",
"alipay": "https://www.crifan.org/files/res/crifan_com/crifan_alipay_pay.jpg",
"title": "",
"button": "打赏",
"alipayText": "支付宝打赏给Crifan",
"wechatText": "微信打赏给Crifan"
}
},
"author": "Crifan Li <admin@crifan.org>",
"language": "zh-hans",
"gitbook": "3.2.3",
"root": "./src",
"links": {
"sidebar": {
"主页": "https://www.crifan.org"
}
},
"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 <admin@crifan.org>",
"language": "zh-hans",
"gitbook": "3.2.3",
"root": "./src",
"links": {
"sidebar": {
"主页": "https://www.crifan.org"
}
},
</code>这部分,被放到中间了。还不是自己希望的,放在开头的位置的效果。