有些配置文件需要导出, 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(' ') 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(', ') 44 s[-1] = ' ' # 防止字典最后一个元素后面跟着逗号 45 s.append(base) 46 s.append('}') 47 elif isinstance(obj, (list, tuple, set)): 48 s.append('[') 49 s.append(' ') 50 for v in obj: 51 pre = base + sep 52 s.append(pre) 53 s.append(bf(v, sep, pre)) 54 s.append(', ') 55 s[-1] = ' ' # 防止数组最后一个元素后面跟着逗号 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 是字符串.