百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Python常用标准库(pickle序列化和JSON序列化)

itomcoil 2025-03-14 18:06 32 浏览

常用的标准库

序列化模块

import pickle

序列化和反序列化

把不能直接存储的数据变得可存储,这个过程叫做序列化。把文件中的数据拿出来,恢复称原来的数据类型,这个过程叫做反序列化。

在文件中存储的数据只能是字符串,或者是字节流,不能是其它的数据类型,但是如果想要将其存储就需要序列化。

Python中的序列化模块叫做 pickle,PHP等其它的一些语言将其称作serialize 或者unserialize,每个语言的序列化功能可以序列化它本身的一切数据类型。

使用场景

现在存在一段数据,现在并不需要他,但是说不定什么时候我就要用它,那么最好的方法就是将这段数据保存起来。

保存这段数据一般来说有那么几种方法(入库或者保存文件),但是这段数据很复杂,而保存在数据库中需要特定的数据格式,入库的话就非常的麻烦了,而且我不想破坏数据的原有格式,那么可以选择保存为文件。

如下所示:保存文件会遇到种种的麻烦问题。

# 这是我想要保存的一段数据
lst = ['A', 'B', 'C']

# 直接使用open函数不能将非字符串和非字节流的数据写入文件
with open('data.txt', 'w', encoding='UTF-8') as fp :
	fp.write(lst)
# !!! TypeError

# 将数据变成字符串就破坏了原有的数据结构(如果很复杂的数据结构几乎没有复原的可能性)
lst = str(lst)

# 将数据变成字节流:只能将字符串变成字节流数据!

现在就可以使用序列化功能,将数据序列化成为字节流的格式,然后存在文件当中,当需要的时候,再从文件中读取出来,然后反序列化成为数据原来的样子,而且保证原数据的数据结构没有变化。

而且可以序列化语言当中的任何数据类型,就是说不止是基本的数据类型,还有函数、类型、对象……

dumps & loads

dumps将任意对象序列化成bytes数据,loads将序列化成为bytes的数据反序列成数据原本的格式。

注意:只能反序列化被序列化的数据

import pickle


# 这是我想要保存的一段数据
lst = ['A', 'B', 'C']


# dumps 把任意对象序列化成bytes
res = pickle.dumps(lst)
print(res)  # b'\x80\x03]q\x00(X\x01\x00\x00\x00Aq\x01X\x01\x00\x00\x00Bq\x02X\x01\x00\x00\x00Cq\x03e.'
print(type(res))  # 
# 序列化后的bytes数据可以写入文件中。


# loads 把任意bytes反序列化成为原来的数据
lst = pickle.loads(res)
print(lst)  # ['A', 'B', 'C']
print(type(lst))  # 


# 尝试反序列化其它的bytes数据
char = '你好'
by_char = char.encode()
new_char = pickle.loads(by_char)  # _pickle.UnpicklingError: invalid load key, '\xe4'.

dump & load

含义和上述的相同,只是这个可以直接操作IO对象,省时省力。

import pickle


# 这是我想要保存的一段数据
lst = ['A', 'B', 'C']


# dumps 和 loads 配合文件操作
# 序列化后写入文件
with open('test.txt', 'wb') as fp:
    data = pickle.dumps(lst)
    fp.write(data)
# 读取文件反序列化
with open('test.txt', 'rb') as fp:
    data = fp.read()
    lst = pickle.loads(data)


# dump 和 load 配合文件操作
# 序列化写入文件
with open('test.txt', 'wb') as fp:
    pickle.dump(lst, fp)
# 读取文件反序列化
with open('test.txt', 'rb') as fp:
    lst = pickle.load(fp)

JSON序列化模块

import json

使用场景

序列化后的数据,如果想在多种语言中都可以流通怎么办?每种语言都有自己的语言特性,有些语言中的数据是特有的,那么序列化后的数据该怎么流通呢?

每种语言虽然各有自己的特点,但是几乎所以的语言都是师出同门,天下语言无不出C者。所以将每种语言共同存在的数据格式按照统一的标准去序列化就可以了,JSON诞生了。

json一般存储为json文件。

支持的数据类型

python中支持JSON序列化的数据一共有八种类型:

int、float、bool、str、list、tuple、dict、None

JSON序列化支持这几种数据类型是因为JSON中就只支持这几种数据类型:

如下为python中的数据类型对应json中的数据类型;

python数据类型

JSON数据类型

int

int

float

float

bool(True,False)

bool(true,false)

None

null

str

str(必须双引号)

list([])、tuple(())

Array([])

dict({})

Object({})(键必须是双引号)

注意:

  1. JSON中没有元组类型,所以会变成列表;
  2. JSON中的对象必须使用字符串作为键,所以python中的字典数据中的非字符串键,会变成对应的JSON数据然后强转成为字符串;
import json

dict_var = {1: 1, 2.2: 2.2, False: True, '123': '123', "234": "234", None: None}

json_obj = json.dumps(dict_var)
dict_var = json.loads(json_obj)

print(dict_var)
# {'1': 1, '2.2': 2.2, 'false': True, '123': '123', '234': '234', 'null': None}

JSON和pickle的区别

JSON可以序列化python八种数据,序列化为字符串

pickle可以序列化python所有的数据类型,序列化为字节流

序列化函数

JSON序列化函数和pickle的一样,名称和使用方法基本一样:

方法

含义

dumps

序列化

loads

反序列化

dump

序列化写入文件

load

读取文件反序列化

这里注意一下序列化方法的几个常用参数:

ensure_asscii 默认为True, 以ACSII格式编码,以Unicode显示;

sort_keys 默认为True, 对字典的键进行排序;

indent默认为None, json格式化默认是一行不加缩进的,如果indent是一个正整数,就以该缩进级别进行换行,增强可视化。

import json

# 开启排序
dict_var = {'B': '2', 'A': '1'}
print(dict_var)  # {'B': '2', 'A': '1'}
json_char = json.dumps(dict_var, ensure_ascii=False, sort_keys=True)
dict_var = json.loads(json_char)
print(dict_var)  # {'A': '1', 'B': '2'}

# 关闭排序
dict_var = {'B': '2', 'A': '1'}
print(dict_var)  # {'B': '2', 'A': '1'}
json_char = json.dumps(dict_var, ensure_ascii=False, sort_keys=False)
dict_var = json.loads(json_char)
print(dict_var)  # {'B': '2', 'A': '1'}

# dump 也一样哦

json和pickle实际使用过程中的一些问题

在对文件进行操作的时候:

  • json可以连续dump,但是不能连续load
  • pickle可以连续dump和load

如下解释:

# json 可以连续dump,但是不能连续load
import json

# 序列化数据
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
lst3 = [7, 8, 9]

# 序列化写入文件
with open('test.json', 'w', encoding='UTF-8') as fp:
    json.dump(lst1, fp)
    json.dump(lst2, fp)
    json.dump(lst3, fp)

# 读取文件反序列化
with open('test.json', 'r', encoding='UTF-8') as fp:
    data1 = json.load(fp)  # ERROR
    data2 = json.load(fp)
    data3 = json.load(fp)

# !!! json.decoder.JSONDecodeError: Extra data: line 1 column 10 (char 9)

因为 json.dump 方法序列化写入文件的时候,写入了两个及以上的数据,之后 json.load 方法在读的时候又是一次性将整个文件中的数据读取出来,这个时候,反序列化的数据成了 [1, 2, 3][4, 5, 6][7, 8, 9] ,这明显不是一个json支持的数据格式,所以 json.load 失败了。

再来看pickle是怎么样的:

# pickle 可以连续dump,也可以连续load
import pickle

# 序列化数据
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
lst3 = [7, 8, 9]

# 序列化写入文件
with open('pickle.txt', 'wb') as fp:
    pickle.dump(lst1, fp)
    pickle.dump(lst2, fp)
    pickle.dump(lst3, fp)

# 读取文件反序列化
with open('pickle.txt', 'rb') as fp:
    data1 = pickle.load(fp)  # [1, 2, 3]
    print(data1)
    data2 = pickle.load(fp)  # [4, 5, 6]
    print(data2)
    data3 = pickle.load(fp)  # [7, 8, 9]
    print(data3)

# 尝试先逐行读取,再反序列化
with open('pickle.txt', 'rb') as fp:
    datum = fp.readlines()
    print(len(datum))  # 1
    
    for data in datum:
        data = pickle.loads(data)
        print(data)  # [1, 2, 3]   # 只能读出一个

可以看到 pickle.load 将数据都读出来了,这是因为 pickle.dump 在写入数据的时候在每条数据后都加上了一个标记(有些人解释说是换行,但是文件中并没有换行,逐行使用 fp.readlines 逐行读取的时候也只能获取一条,但是在文件中所有的数据都是在同一行的,我也不太懂了(无奈)),然后 pickle.load 每次就只会读一条数据,从IO指针读到每条数据后的那个标记为止,所以,pickle 可以连续的 load

怎么解决json的这个问题?

其实上面的这个问题,我个人认为是一种不规范的操作。因为 json.load 会一次性的读取整个文件中的内容,你却在一个文件中写入了不止一条的数据,那么在反序列化的时候当然会报错了。所以我认为:

json的主要作用多语言之前的数据传递和数据存储,每个JSON文件中最好只储存一条完整的数据。

但是我就想在一个json文件中存多个数据呢?

其实思路很简单,关键就是读取文件然后反序列化的时候,必须是一条数据、一条数据的反序列化,类似如下:

import json

# 序列化数据
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]
lst3 = [7, 8, 9]

# 序列化写入文件,每写入一条数据插一个换行
with open('test.json', 'w', encoding='UTF-8') as fp:
    json.dump(lst1, fp)
    fp.write('\n')
    json.dump(lst2, fp)
    fp.write('\n')
    json.dump(lst3, fp)

# 读取文件反序列化(逐行读取数据,然后反序列化)
with open('test.json', 'r', encoding='UTF-8') as fp:
    datum = fp.readlines()
    print(len(datum))  # 3

    for data in datum:
        data = json.loads(data)
        print(data)  # [1, 2, 3]
                     # [4, 5, 6]
                     # [7, 8, 9]

pickle和json的区别总结

  1. json序列化后的数据为字符串,pickle序列化后的数据为字节流;
  2. json支持八种数据类型(int、float、bool、str、list、tuple、dict、None),pickle支持python的一切数据类型;
  3. json一般用于多语言间的数据交流,pickle一般用于python之间数据交流;

文章来自
https://www.cnblogs.com/msr20666/p/16308669.html

相关推荐

python创建文件夹,轻松搞定,喝咖啡去了

最近经常在录视频课程,一个课程下面往往有许多小课,需要分多个文件夹来放视频、PPT和案例,这下可好了,一个一个手工创建,手酸了都做不完。别急,来段PYTHON代码,轻松搞定,喝咖啡去了!import...

如何编写第一个Python程序_pycharm写第一个python程序

一、第一个python程序[掌握]python:python解释器,将python代码解释成计算机认识的语言pycharm:IDE(集成开发环境),写代码的一个软件,集成了写代码,...

Python文件怎么打包为exe程序?_python3.8打包成exe文件

PyInstaller是一个Python应用程序打包工具,它可以将Python程序打包为单个独立可执行文件。要使用PyInstaller打包Python程序,需要在命令行中使用py...

官方的Python环境_python环境版本

Python是一种解释型编程开发语言,根据Python语法编写出来的程序,需要经过Python解释器来进行执行。打开Python官网(https://www.python.org),找到下载页面,选择...

[编程基础] Python配置文件读取库ConfigParser总结

PythonConfigParser教程显示了如何使用ConfigParser在Python中使用配置文件。文章目录1介绍1.1PythonConfigParser读取文件1.2Python...

Python打包exe软件,用这个库真的很容易

初学Python的人会觉得开发一个exe软件非常复杂,其实不然,从.py到.exe文件的过程很简单。你甚至可以在一天之内用Python开发一个能正常运行的exe软件,因为Python有专门exe打包库...

2025 PyInstaller 打包说明(中文指南),python 打包成exe 都在这里

点赞标记,明天就能用上这几个技巧!linux运维、shell、python、网络爬虫、数据采集等定定做,请私信。。。PyInstaller打包说明(中文指南)下面按准备→基本使用→常用...

Python自动化办公应用学习笔记40—文件路径2

4.特殊路径操作用户主目录·获取当前用户的主目录路径非常常用:frompathlibimportPathhome_dir=Path.home()#返回当前用户主目录的Path对象...

Python内置tempfile模块: 生成临时文件和目录详解

1.引言在Python开发中,临时文件和目录的创建和管理是一个常见的需求。Python提供了内置模块tempfile,用于生成临时文件和目录。本文将详细介绍tempfile模块的使用方法、原理及相关...

python代码实现读取文件并生成韦恩图

00、背景今天战略解码,有同学用韦恩图展示各个产品线的占比,效果不错。韦恩图(Venndiagram),是在集合论数学分支中,在不太严格的意义下用以表示集合的一种图解。它们用于展示在不同的事物群组之...

Python技术解放双手,一键搞定海量文件重命名,一周工作量秒搞定

摘要:想象一下,周五傍晚,办公室的同事们纷纷准备享受周末,而你,面对着堆积如山的文件,需要将它们的文件名从美国日期格式改为欧洲日期格式,这似乎注定了你将与加班为伍。但别担心,Python自动化办公来...

Python路径操作的一些基础方法_python路径文件

带你走进@机器人时代Discover点击上面蓝色文字,关注我们Python自动化操作文件避开不了路径操作方法,今天我们来学习一下路径操作的一些基础。Pathlib库模块提供的路径操作包括路径的...

Python爬取下载m3u8加密视频,原来这么简单

1.前言爬取视频的时候发现,现在的视频都是经过加密(m3u8),不再是mp4或者avi链接直接在网页显示,都是经过加密形成ts文件分段进行播放。今天就教大家如果通过python爬取下载m3u8加密视频...

探秘 shutil:Python 高级文件操作的得力助手

在Python的标准库中,shutil模块犹如一位技艺精湛的工匠,为我们处理文件和目录提供了一系列高级操作功能。无论是文件的复制、移动、删除,还是归档与解压缩,shutil都能以简洁高效的方式完成...

怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!

前面用Python+Flet开发的“我的计算器v3”,怎么打包为exe文件呢?这样才能分发给他人,直接“双击”运行使用啊!今天我给大家分享一个简单的、可用的,把Flet开发的程序打包为...