每次在写入文件的时候就很头疼,最喜欢写成json文件,因为保存数据的时候,一般都用字典保存数据,然后使用一个json模块,就可以转化为可以保存的字符串了。但是平时除了写入json,还要写入表格里,因为表格可视性好,还有筛选等等强大的功能,所以也会保存一份表格类型。之前喜欢保存Excel格式,但是总有编解码问题,实在太讨厌了!!! 后来随着数据分析的学习,觉得保存csv很方便,而且代码量减少很多,所以如果写表格会推荐保存csv格式。

>下面分享一下封装好的保存文件的类<

Python将字典数据保存为Json文件

"""
将字典对象保存为Json文件
"""

import os
import json


class SaveJson(object):

    def save_file(self, path, item):
        
        # 先将字典对象转化为可写入文本的字符串
        item = json.dumps(item)

        try:
            if not os.path.exists(path):
                with open(path, "w", encoding='utf-8') as f:
                    f.write(item + ",\n")
                    print("^_^ write success")
            else:
                with open(path, "a", encoding='utf-8') as f:
                    f.write(item + ",\n")
                    print("^_^ write success")
        except Exception as e:
            print("write error==>", e)


if __name__ == '__main__':
    # 保存的文件名
    path = "test1.json"
    # 案例字典数据
    item = {"uid": "5bc05421vbjgj34hj9c7d83", "oss_status_code": 200,
            "url": "https://ssyerv2.oss-cn-hangzhou.aliyuncs.com//picture/zl/687122.jpg",
            "updatedAt": "1970-01-18", "createdAt": "1970-01-18", "PID": "5b923c7vbcvbxcswrw342504b",
            "_id": "5b98d052ed0cbe41","CID":"afdsfgasgfafghdgssdhh"}

    s = SaveJson()

    # 测试代码,循环写入三行,没有空行
    for i in range(3):
        s.save_file(path, item)

Python将字典数据保存为CSV文件

"""
将字典对象保存为excel
"""

import json
import os
import csv


class SaveCSV(object):

    def save(self, keyword_list,path, item):
        """
        保存csv方法
        :param keyword_list: 保存文件的字段或者说是表头
        :param path: 保存文件路径和名字
        :param item: 要保存的字典对象
        :return:
        """
        try:
            # 第一次打开文件时,第一行写入表头
            if not os.path.exists(path):
                with open(path, "w", newline='', encoding='utf-8') as csvfile:  # newline='' 去除空白行
                    writer = csv.DictWriter(csvfile, fieldnames=keyword_list)  # 写字典的方法
                    writer.writeheader()  # 写表头的方法

            # 接下来追加写入内容
            with open(path, "a", newline='', encoding='utf-8') as csvfile:  # newline='' 一定要写,否则写入数据有空白行
                writer = csv.DictWriter(csvfile, fieldnames=keyword_list)
                writer.writerow(item)  # 按行写入数据
                print("^_^ write success")

        except Exception as e:
            print("write error==>", e)
            # 记录错误数据
            with open("error.txt", "w") as f:
                f.write(json.dumps(item) + ",\n")
            pass


if __name__ == '__main__':
    # 保存的文件名
    path = "test1.csv"
    # 案例字典数据
    item = {'num': 60, 'keyword': '软 件 开 发'}
    # 保存的表头
    item_list = [
        "keyword",
        "num"
    ]
    s = SaveCSV()
    # 测试代码,循环写入三行,没有空行
    for i in range(3):
        s.save(item_list ,path, item)

可能会出现的问题

一、写csv文件编码问题

参考文章:Python UnicodeEncodeError: ‘gbk’ codec can’t encode character
解决方法 :http://www.jb51.net/article/64816.htm

  • 重要点:目标文件的编码是导致标题所指问题的罪魁祸首。如果我们打开一个文件,在windows下面,新文件的默认编码是gbk,这样的话,python解释器会用gbk编码去解析我们的网络数据流txt,然而txt此时已经是decode过的unicode编码,这样的话就会导致解析不了,出现上述问题。 解决的办法就是,改变目标文件的编码。
  • 解决方案:
###### 确实最推荐的做法是在open文件时,指定编码格式:
with open(f"{DATABASE}_{TABLE}.csv", "w", newline='', encoding='utf-8') as csvfileWriter:
# 就像我们在windows环境下,写csv文件时,默认编码是'gbk',而从网上获取的数据大部分是'utf-8',这就可能出现某些编码不兼容的问题。比如:write csv exception. e = 'gbk' codec can't encode character '\xae' in position 80: illegal multibyte sequence
二、写csv文件出现空白行(存在一行间一行)

python2.x 版本
描述及解决方案,请参考:

# 为了解决这个问题,查了下资料,发现这是和打开方式有关,将打开的方法改为wb,就不存在这个问题了,也就是
在read/write csv 文件是要以binary的方式进行。
with open('result.csv','wb') as cf:
        writer = csv.writer(cf)
        writer.writerow(['shader','file'])
        for key , value in result.items():
            writer.writerow([key,value])

python2.x要用‘wb’模式写入的真正原因:
python2.x中写入CSV时,CSV文件的创建必须加上‘b’参数,即open(‘result.csv’,‘wb’),不然会出现隔行的现象。原因是:python正常写入文件的时候,每行的结束默认添加’n’,即0x0D,而 writerow 命令的结束会再增加一个0x0D0A,因此对于windows系统来说,就是两行,而采用’ b’参数,用二进制进行文件写入,系统默认是不添加0x0D的
而且在python2.x中,str和bytes是存在很多隐性转换的,所以虽然CSV是文本文件,也是可以正常写入。

python3 版本
在python3中,str和bytes有了清晰的划分,也没有任何隐性的转换,csv 是文本格式的文件,不支持二进制的写入,所以不要用二进制模式打开文件,数据也不必转成bytes。
描述及解决方案,请参考:

# 解决方案就是 newline 配置成空即可
with open('result.csv', 'w', newline='') as csvfile:
  • 总结一下:出现空白行的根本原因是Python版本问题,解决方案上python2.x中要求用‘wb’,python3.x中要求用 ‘w’ 和newline参数。
  • 拓展:关于python3中bytes和string之间的互相转换:http://www.jb51.net/article/105064.htm