有些配置文件需要導出, json格式非常便利, 但是可讀性太差.
json 格式字符串往往是一行, 並且漢字會轉義.
所以寫了這個工具.
目標有兩個:
- 轉成json 格式, 支持被json.loads 加載
- 提高可讀性, 增加換行和縮進
代碼:
1 """ 2 python3.6+ 3 dict 轉 json 字符串 4 並美化, 可讀 5 """ 6 7 __addrs = set() 8 9 10 def bf(obj, sep=' ', base=''): 11 """ 12 :param obj: dict/list/tuple/set/str/int/float/ 13 :param sep: 分隔符 14 :param base: 15 :return: 16 """ 17 s = [] 18 if isinstance(obj, str): 19 return f'"{obj}"' 20 if isinstance(obj, bool): 21 return 'true' if obj else 'false' 22 if isinstance(obj, (int, float)): 23 return str(obj) 24 if obj is None: 25 return 'null' 26 # 27 x = id(obj) 28 if x in __addrs: 29 return f'"遞歸調用:<{x}>"' 30 else: 31 __addrs.add(x) 32 if isinstance(obj, dict): 33 s.append('{') 34 s.append('\n') 35 for k in obj: 36 v = obj[k] 37 pre = base + sep 38 s.append(pre) 39 s.append('"') 40 s.append(str(k)) 41 s.append('":') 42 s.append(bf(v, sep, pre)) 43 s.append(',\n') 44 s[-1] = '\n' # 防止字典最后一個元素后面跟着逗號 45 s.append(base) 46 s.append('}') 47 elif isinstance(obj, (list, tuple, set)): 48 s.append('[') 49 s.append('\n') 50 for v in obj: 51 pre = base + sep 52 s.append(pre) 53 s.append(bf(v, sep, pre)) 54 s.append(',\n') 55 s[-1] = '\n' # 防止數組最后一個元素后面跟着逗號 56 s.append(base) 57 s.append(']') 58 else: 59 s.append(f'"不支持對象:{str(type(obj))}"') 60 return ''.join(s) 61 62 63 if __name__ == '__main__': 64 obj = { 65 'haozhene': True, 66 'workers': [1,2,3, {'a': {1,2,3}, 1:[1,2,3]}], 67 'push_name': '???', 68 'start_time': True, 69 'status': 0, 70 'err_msg': None, 71 'uuid_size': 0, 72 'tails': '', 73 'tais': {1:1,2:2, 3:True}, 74 'tails1': ('a', [1], {'a': False}), 75 'tails2': (), 76 'tails3': {}, 77 } 78 obj['xx'] = obj 79 s = bf(obj) 80 print(s) 81 import json 82 new_obj = json.loads(s) 83 print(new_obj)
注意事項:
1. 對於除了(int/float/str/dict/list/set) 以外的對象都不支持, 請自行轉成字符串.
(否則: 會執行
s.append(f'"不支持對象:{str(type(obj))}"')
)
2. 對於遞歸調用, 會跳出, 變成: "遞歸調用:<4410538256>"
3. python的字典key 支持很多類型, 統一調用了str 方法.
{1: "something"} 調用這個方法后會變成: {"1" : "something"}
因為標准json格式的key 是字符串.
