Python3对象序列化,即处理JSON和文件(持续更新ing...)

诸神缄默不语-个人技术博文与视频目录

本文主要关注如何将各种Python对象储存为本地文件,并反之从本地文件加载Python对象。
(注意:一般情况下Python读写的工具都需要统一,如果可以跨工具使用的话,我会在对应内容的位置说明)

数据库就不算在内了,Python与数据库的交互我写了别的博文。

对XML对象的处理我单拎出来写了一篇博文:XML文件格式的简介及如何用Python3处理XML格式对象

1. 使用Python3原生函数读写文件流

Python3使用原生函数open()可以直接打开本地文件,返回值是文件流。
参数:

  • 文件路径
  • 打开模式,默认为r只读。其他可选项:w写入,a添加,rb/wb后面的b指对二进制文件的处理1
  • encoding:编码格式,常用选项为utf-8gbk

有两种常见写法,一种是将open()作为命令,对返回的文件流进行处理,最后要记得close();一种是将open()作为上下文管理器,如with open('file.txt') as f:语句下包裹的代码运行之间自动打开文件流,运行完毕后自动关闭。
(如果对with语句之外的f进行I/O操作,将会报:ValueError: I/O operation on closed file.这个bug)

对文件流的操作:

  • readlines() 对于文本文件,就是返回全部内容,列表格式,每行文字是一个元素
  • read() 对于文本文件,就是返回全部内容,字符串格式
  • write(str) 写入一个字符串对象
  • writelines(obj) 写入一个可迭代对象的所有元素,obj需要元素是字符串。注意:1. 不会自动换行。2. 集合对象也可以写入,但顺序随机;以字符串为键的字典对象也可以写入,但将只写入键值,具体的顺序我不确定。
  • flush()2 刷新内部缓冲(意思就是更新代码中各种写入操作)(在文件关闭时也会自动刷新一次)
  • close() 关闭文件流(如果使用with open()就不用显式关闭文件流)

2. JSON

Python 3内置json包

加载本地文件到内存中:json.load(文件流)
将Python对象储存到本地:json.dump(Python对象,文件流)
(文件流是通过open()函数打开的)

将字符串对象转换为dict对象:json.loads(str)
将dict对象转换为字符串:json.dumps(obj)

dump()dumps()的共有入参:

  • ensure_ascii:默认置True, 这会导致转换得到的字符串无法用肉眼直接阅读。所以一般都会显式置False

使用JSON来储存数据的优势在于跨平台、跨语言。

在这里额外提供一些别的JSON工具包:

  • json格式化(就算是不严格的JSON也可以格式化,比原始文本易读多了):https://www.bejson.com/

3. 使用pickle包

pickle包官方文档:https://docs.python.org/3/library/pickle.html

将Python对象储存为本地文件:

import pickle

data = [1, 2, 3, {'k': 'A1', '全文': '内容1'}] # 你的数据

with open('data.pkl', 'wb') as file:
    pickle.dump(data, file)

加载本地文件到内存中:

import pickle

with open('data.pkl', 'rb') as file:
    loaded_data = pickle.load(file)

print(loaded_data) # 输出: [1, 2, 3, {'k': 'A1', '全文': '内容1'}]

4. 处理CSV:csv包

csv包官方文档:csv — CSV File Reading and Writing — Python 3.11.0 documentation

从CSV文件中读数据:

import csv
with open(CSV文件名,newline='') as csvfile:
	spamwreader=csv.reader(csvfile)
	for row in spamreader:
		#一行数据,列表对象,每个元素是该行的一个cell

将数据写入到CSV文件中:

import csv
with open(CSV文件名,'w',newline='') as csvfile:
    spamwriter=csv.writer(csvfile)
    spamwriter.writerow(一行列表对象(每个元素是该行的一个cell))

5. 处理Excel

1. xlsx: openpyxl包

openpyxl包官方中文文档:openpyxl - 读/写 Excel 2010 xlsx/xlsm 文件的 Python 库 — openpyxl 3.0.7 文档
安装openpyxl:pip install openpyxl

  1. 创建Workbook对象(相当于一个Excel文件)
    1. 新建一个(会默认创建一个sheet):
    from openpyxl import Workbook
    wb=Workbook()
    
    1. 打开Excel文件:
    from openpyxl import load_workbook
    wb2 = load_workbook('test.xlsx')
    
  2. 获取第一个sheet:ws = wb.active
  3. 创建sheet:ws=wb.create_sheet(sheet_name)(返回sheet)
  4. 通过sheet_name获取sheet:ws=wb[sheet_name]
  5. 打印所有的sheet_name:wb.sheetnames(返回一个列表对象)
  6. 提取某一元素(如果没有元素将自动创建空值)
    从1开始
    1. ws.cell(row=line_index,column=column_index,value=jiancheng):定义value会自动赋值
    2. ws['A1']:直接用单元格提取,可以直接赋值
  7. ws.iter_rows(min_row=None, max_row=None, min_col=None, max_col=None, values_only=False):默认从A1开始
    如果置value_only=True,返回值是一个元素的迭代器
  8. 将对象插入Excel:
    1. 将list插入Excel:ws.append(list_object)
    2. 将dict插入Excel:ws.append(list(dict_object.values()))
  9. 将Workbook对象储存到Excel文件中(警告:这个操作将会无警告直接覆盖已有文件):wb.save('an_excel.xlsx')
  10. 其他注意事项
    1. 使用openpyxl包在Linux上编程时,发现sheet name只是不允许添加/;但把excel文件下载到本地后会发现也不允许添加,office会自动把非法文字给删掉。所以建议在编程的时候就不要创建这种内容
    2. 如果试图用openpyxl包调用.xls文件,会得到如下报错信息:InvalidFileException: openpyxl does not support the old .xls file format, please use xlrd to read this file, or convert it to the more recent .xlsx file format.

openpyxl的更多进阶用法可以参考我写的其它博文:

  1. 单元格填色:styles.PatternFill
    Excel如何给单元格填色,以及如何用Python 3实现单元格填色
  2. 合并单元格:ws.merge_cells("A4:A5")
  3. 行分级:ws.row_dimensions.group(8, 96, outline_level=1)
    折叠分级按钮:ws.sheet_properties.outlinePr.summaryBelow = False
    Excel如何实现行分级,以及如何用Python 3实现Excel行分级

2. xls:xlrd包

xlrd — xlrd 2.0.1 documentation

安装:pip install xlrd

使用示例:

import xlrd
book = xlrd.open_workbook("myfile.xls")
print("The number of worksheets is {0}".format(book.nsheets))
print("Worksheet name(s): {0}".format(book.sheet_names()))
sh = book.sheet_by_index(0)
print("{0} {1} {2}".format(sh.name, sh.nrows, sh.ncols))
print("Cell D30 is {0}".format(sh.cell_value(rowx=29, colx=3)))
for rx in range(sh.nrows):  #按行循环
    print(sh.row(rx))  #一个列表,每个元素是一格,一个xlrd.sheet.Cell
    print(sh.row(rx)[0].value)  #第一格的值

6. word文件:python-docx库

可以参考我撰写的博文:深入解析Python-docx库:轻松玩转Word文档自动化

7. 使用numpy包

1 一次性序列化多个对象

习惯以.npz后缀存储

官方文档:https://numpy.org/devdocs/reference/generated/numpy.savez.html
https://numpy.org/devdocs/reference/generated/numpy.savez_compressed.html

8. 使用scipy包

1 scipy.sparse

习惯以.npz后缀存储

储存对象:save_npz()(官方文档:https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.save_npz.html

import scipy.sparse
sparse_matrix = scipy.sparse.csc_matrix(np.array([[0, 0, 3], [4, 0, 0]]))
scipy.sparse.save_npz('/tmp/sparse_matrix.npz', sparse_matrix)

加载本地对象:load_npz()(官方文档:https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.load_npz.html

import scipy.sparse
sparse_matrix = scipy.sparse.load_npz('/tmp/sparse_matrix.npz')

9. 使用pandas包

1 CSV/Excel文件

10. 使用sklearn包

11. 使用PyTorch包

习惯以.pt.pth后缀存储

PyTorch储存与加载模型的官方教程:Saving and Loading Models — PyTorch Tutorials 1.12.1+cu102 documentation
其他参考资料:python - How do I save a trained model in PyTorch? - Stack Overflow

将对象储存到磁盘:torch.save(obj,path)
将磁盘对象加载到内存:torch.load(path)
(path可以是路径字符串或文件流)

load()入参:

  • map_location:可以是函数、torch.device、字符串或字典,指定对象存储的设备位置。

获取模型参数(返回state_dict,匹配模型层到参数张量的字典文件,只包括可学习的那些。优化器对象也有这个):model.state_dict() optimizer.state_dict()
将模型参数加载回模型:model.load(state_dict)

所以直接储存模型参数就是:torch.save(model.state_dict(), path)
直接加载模型参数就是:model.load_state_dict(torch.load(path))

需要注意的一个情况是:如果在每个epoch后,都根据当前指标,保存最好指标下的epoch的checkpoint,因为state_dict是mutable对象OrderedDict,所以直接引用(best_state = model.state_dict())的话会跟着模型的当前指标变化,因此需要深拷贝(best_state = copy.deepcopy(model.state_dict())3

12. 使用transformers包

13. 处理PDF

我现在依然不会用Python直接从PDF中提取格式。GPT-4说它也没辙:
在这里插入图片描述
(2023.6.21更新:看了一下,好像PyMuPDF可以,我还没试)

1 PyPDF2:逐页提取文字

请参考我之前撰写的博文:PyPDF2:使用Python操作PDF文件

2 tabula-py:提取表格

tabula-py · PyPI

表格之外的内容全都无法提取(嗯所以我个人的解决方案是结合别的处理PDF的包一起使用)
安装方式:pip install tabula-py
注意:1. 如果想要使用这个包的话,需要安装Java 2. 这个包无法完全提取文档中的表格,有时会遗漏,有条件的话还是需要自己检查一遍的

import tabula
# 读取PDF文件
file = "中国计算机学会推荐国际学术会议和期刊目录-2022(拟定).pdf"
# 使用tabula读取PDF中的表格
tables = tabula.read_pdf(file, pages = "all", multiple_tables = True)  #pages可以是int,int列表,或者'all'
# `tables`现在是一个包含所有表格的列表,每个表格都是一个pandas DataFrame
# 您可以通过索引来访问每个表格,例如:
first_table = tables[20]
# 打印第19个表格的内容
print(tables[20])

输出:

    序号     会议简称                                               会议全称        出版社                                                 网址
0    1       CF  ACM International Conference on Computing Fron...        ACM                http://dblp.uni-trier.de/db/conf/cf
1    2   SYSTOR   ACM International Systems and Storage Conference        ACM  http://dblp.uni-trier.de/db/conf/systor/index....
2    3     NOCS  ACM/IEEE International Symposium on Networks-o...   ACM/IEEE              http://dblp.uni-trier.de/db/conf/nocs
3    4     ASAP  Application-Specific Systems, Architectures, a...       IEEE              http://dblp.uni-trier.de/db/conf/asap
4    5  ASP-DAC  Asia and South Pacific Design Automation Confe...   ACM/IEEE            http://dblp.uni-trier.de/db/conf/aspdac
5    6      ETS                            European Test Symposium       IEEE              http://dblp.uni-trier.de/db/conf/ets/
6    7      FPL          Field Programmable Logic and Applications       IEEE              http://dblp.uni-trier.de/db/conf/fpl/
7    8     FCCM       Field-Programmable Custom Computing Machines       IEEE             http://dblp.uni-trier.de/db/conf/fccm/
8    9  GLSVLSI                      Great Lakes Symposium on VLSI   ACM/IEEE           http://dblp.uni-trier.de/db/conf/glvlsi/
9   10      ATS                          IEEE Asian Test Symposium       IEEE              http://dblp.uni-trier.de/db/conf/ats/
10  11     HPCC  IEEE International Conference on High Performa...       IEEE             http://dblp.uni-trier.de/db/conf/hpcc/
11  12     HiPC  IEEE International Conference on High Performa...  IEEE/ ACM   http://dblp.uni-trier.de/db/conf/hipc/index.html
12  13  MASCOTS  IEEE International Symposium on Modeling, Anal...       IEEE          http://dblp.uni-trier.de/db/conf/mascots/

3 PDFMiner

pdfminer · PyPI

安装:pip install pdfminer

pdf2txt.py [-P password] [-o output] [-t text|html|xml|tag]
             [-O output_dir] [-c encoding] [-s scale] [-R rotation]
             [-Y normal|loose|exact] [-p pagenos] [-m maxpages]
             [-S] [-C] [-n] [-A] [-V]
             [-M char_margin] [-L line_margin] [-W word_margin]
             [-F boxes_flow] [-d]
             input.pdf

挺复杂的,总之我实验过txt和html两种文件,TXT就是纯纯转换为文本,我的意见是不如用PyPDF2,好歹能知道原本的页数;HTML看起来不能复原原文件中的背景色和字体,但是会以某种方式呈现出来。
但可能是因为我HTML没学好,反正我看起来觉得实在是太混乱了,我懒得研究了,我就放弃用这个包了。

4 pdfplumber

jsvine/pdfplumber: Plumb a PDF for detailed information about each char, rectangle, line, et cetera — and easily extract text and tables.

安装方式:pip install pdfplumber

提取表格(我的使用体验是不如tabula):

pdf = pdfplumber.open(pdf_file_path)
page = pdf.pages[page_index]
if not page.extract_table() is None:  #说明提取出表格了,do something!
    pass

5 PyMuPDF

官方文档:PyMuPDF 1.22.3 documentation

安装方式:pip install pymupdf

  1. 打开文件(是一个由fitz.fitz.Page对象组成的列表)
    import fitz
    doc = fitz.open(PDF路径)
    
  2. fitz.fitz.Page中提取文本:page.get_text() 返回字符串对象
    入参:
    • "blocks":返回元组列表,每个元组的格式类似这样:(107.57489776611328, 246.74249267578125, 505.5909118652344, 282.74249267578125, '专业学位硕士学位论文 \n', 0, 0):包含了block的位置信息
    • “words”:返回单词及对应的位置信息
  3. fitz.fitz.Page中提取图片:page.get_images()返回图片。将图片保存为png格式:
    image_list = page.get_images()
    for image_index, img in enumerate(image_list, start=1): # enumerate the image list
       xref = img[0] # get the XREF of the image
       pix = fitz.Pixmap(doc, xref) # create a Pixmap
    
       if pix.n - pix.alpha > 3: # CMYK: convert to RGB first
           pix = fitz.Pixmap(fitz.csRGB, pix)
    
       pix.save("图"+str(image_number)+".png") # save the image as png
       pix = None
       image_number+=1
    

6 pdfreader

pypi官网:pdfreader · PyPI

14. 处理LaTeX

pylatex包
参考博文:

  1. Pylatex module in python - GeeksforGeeks

15. 本文撰写过程中使用的其他参考资料

  1. Python 处理Excel文件为了通用原则,建议用openpyxl库 - 简书
  2. Python xlrd read as string - Stack Overflow
  3. Python解析xml字符串_jack@london的博客-CSDN博客
  4. Python XML 解析 | 菜鸟教程
  5. XML 教程
  6. 【python小随笔】python解析xml格式字符串与xml文件
  7. python3基础:操作xml
  8. python无损提取pdf中的图片 - 知乎

  1. [Python] 详细解答 open 函数中 r 和 rb 的区别 - 简书 ↩︎

  2. Python3 file.flush()方法 - Python3教程 ↩︎

  3. python - best_state changes with the model during training in pytorch - Stack Overflow ↩︎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诸神缄默不语

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值