w84944422 发表于 2017-2-27 18:41:08

Python保存json文件并格式化

最近自己用python开发一些小东西,需要用json文件存储些文件属性什么的,但是发现用 json 包里的 json.dump() 方法存json文件的效果好丑……(其实是没仔细看方法), 于是上网找了一份格式化json文件的代码,效果挺不错,用了递归的思想,学习了一波并找到了其中一点小bug。然后,发现其实 json.dump() 方法其实只需要设置一个参数就达到格式化的效果了……  下面介绍一下 json.dump() 和我 修改后的那份代码。  json.dump()  直接把常用参数列一下好了也就是说在使用 json.dump() 的时候设置一下 indent 参数的值就好了。比如 json.dump(json_dict, f, indent=4) ,加与不加的区别如下:  {"title_pinyin":"gywxw","title":"隔云勿相望","url":"http://www.ty2016.net/book/gywxw/","description":"大学刚毕业,她嫁给了林安森可是结婚三年,电视上常看到他出席各种场合携女相伴,她却再没再亲眼见过他。"}  {  "title_pinyin":"gywxw",  "title":"隔云勿相望",  "url":"http://www.ty2016.net/book/gywxw/",  "description":"大学刚毕业,她嫁给了林安森可是结婚三年,电视上常看到他出席各种场合携女相伴,她却再没再亲眼见过他。"  }  递归实现  直接粘过来了,不难理解,效果跟上边是一样的。  # -*- encoding: utf-8 -*-  class JsonFormatter:  def __init__(self, intend=4, name="", encoding="utf-8"):  '''  intend: 缩进空格数  name: 文件名  encoding: 文件编码  '''  self.name = name  self.intend = intend  self.encoding = encoding  self.stack = []  self.obj = None  self.source = self.get_source(name, self.encoding)  self.prepare()  @staticmethod  def json_str(s):  '''  给字符串套上双引号  '''  return '"' + s + '"'  @staticmethod  def get_source(name, encoding="utf-8"):  with open(name, 'r', encoding=encoding) as f:  # 当不给split函数传递任何参数时,分隔符sep会采用任意形式的空白字符:空格、tab、换行、回车以及换页符  return ''.join(f.read().split())  def prepare(self):  try:  # python对象和json格式还是略有不同  self.source = self.source.replace("null", "None").replace("true", "True").replace("false", "False")  self.obj = eval(self.source)  except:  # json string 一定满足python dict和list的组合  raise Exception('Invalid json string!')  def line_intend(self, level=0):  return '\n' + ' ' * self.intend * level  def parse_dict(self,obj=None,intend_level=0):  if intend_level == 0:  # 这个判断是为了防止文件开头出现空行  self.stack.append('{')  else:  self.stack.append(self.line_intend(intend_level)+'{')  intend_level += 1  i = 0  for key, value in obj.items():  key = self.json_str(str(key))  self.stack.append(self.line_intend(intend_level)+key+':')  self.parse(value, intend_level)  if i != len(obj.items())-1:  # 这个处理是为了防止最后一对kv后面还有个逗号,这样会造成json.load()函数无法读取  self.stack.append(',')  i += 1  self.stack.append(self.line_intend(intend_level-1)+'}')  def parse_list(self, obj=None, intend_level=0):  if intend_level == 0:  self.stack.append('[')  else:  self.stack.append(self.line_intend(intend_level)+'[')  intend_level += 1  for i, item in zip(range(0, len(obj)), obj):  self.parse(item, intend_level)  if i != len(obj)-1:  self.stack.append(',')  self.stack.append(self.line_intend(intend_level-1)+']')  def parse(self, obj, intend_level=0):  if obj is None:  self.stack.append('null')  elif obj is True:  self.stack.append('true')  elif obj is False:  self.stack.append('false')  elif isinstance(obj, (int, float)):  self.stack.append(str(obj))  elif isinstance(obj, str):  self.stack.append(self.json_str(obj))  elif isinstance(obj, (list, tuple)):  self.parse_list(obj, intend_level)  elif isinstance(obj, dict):  self.parse_dict(obj, intend_level)  else:  raise Exception('Invalid json type %s!' % obj)  def render(self):  self.parse(self.obj, 0)  res_file = self.name  res = ''.join(self.stack)  with open(res_file, 'w', encoding=self.encoding) as f:  f.write(res)  if __name__ == "__main__":  jf = JsonFormatter(name="json.txt")  jf.render() 来源:孔天逸'Blog
页: [1]
查看完整版本: Python保存json文件并格式化