常用的标准库

序列化模块

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)) # <class 'bytes'>
# 序列化后的bytes数据可以写入文件中。 # loads 把任意bytes反序列化成为原来的数据
lst = pickle.loads(res)
print(lst) # ['A', 'B', 'C']
print(type(lst)) # <class 'list'> # 尝试反序列化其它的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之间数据交流;

Python常用标准库(pickle序列化和JSON序列化)的更多相关文章

  1. python 常用标准库

    标准库和第三方库第一手资料: 在线: 官方文档(https://docs.python.org/) 离线:交互式解释器(dir().help()函数),IPython(tab键提示.?.??) 一.  ...

  2. python常用标准库(时间模块 time和datetime)

    常用的标准库 time时间模块 import time time -- 获取本地时间戳 时间戳又被称之为是Unix时间戳,原本是在Unix系统中的计时工具. 它的含义是从1970年1月1日(UTC/G ...

  3. python常用标准库(os系统模块、shutil文件操作模块)

    常用的标准库 系统模块 import os 系统模块用于对系统进行操作. 常用方法 os模块的常用方法有数十种之多,本文中只选出最常用的几种,其余的还有权限操作.文件的删除创建等详细资料可以参考官方文 ...

  4. python常用标准库(压缩包模块zipfile和tarfile)

    常用的标准库 在我们常用的系统windows和Linux系统中有很多支持的压缩包格式,包括但不限于以下种类:rar.zip.tar,以下的标准库的作用就是用于压缩解压缩其中一些格式的压缩包. zip格 ...

  5. python常用标准库(math数学模块和random随机模块)

    常用的标准库 数学模块 import math ceil -- 上取整 对一个数向上取整(进一法),取相邻最近的两个整数的最大值. import math res = math.ceil(4.1) p ...

  6. python常用标准库

    -------------------系统内建函数------------------- 1.字符串     str='这是一个字符串数据测试数据'对应     str[0]:获取str字符串中下标为 ...

  7. Python常用标准库之datetime、random、hashlib、itertools

    库:具有相关功能模块的集合 import sys.builtin_module_names #返回内建模块的名字modules 查看所有可用模块的名字 1.1.1获取当前日期和时间 from date ...

  8. 【循序渐进学Python】11.常用标准库

    安装完Python之后,我们也同时获得了强大的Python标准库,通过使用这些标准库可以为我们节省大量的时间.这里是一些常用标准库的简单说明.更多的标准库的说明,可以参考Python文档 sys 模块 ...

  9. python进阶05 常用问题库(1)json os os.path模块

    python进阶05 常用问题库(1)json os os.path模块 一.json模块(数据交互) web开发和爬虫开发都离不开数据交互,web开发是做网站后台的,要跟网站前端进行数据交互 1.什 ...

随机推荐

  1. 2015 年十佳 HTML5 应用

    前言 优秀的前端工程师戴着脚铐跳舞,究竟能把 HTML5 的体验推进到什么程度? 这些 Web apps 是我们运营云集浏览器的网上应用店一年来,我选出的十佳 Web apps.其中参考了同事们的意见 ...

  2. 用纯CSS美化radio和checkbox

    Radio和checkbox需要美化吗?答案是必须的,因为设计风格一直都会变化,原生的样式百年不变肯定满足不了需求. 先看看纯CSS美化过后的radio和checkbox效果:查看. 项目地址:mag ...

  3. 【java】密码检查

    [问题描述] 开发一个密码检查软件,密码要求: 长度超过8位 包括大小写字母.数字.其它符号,以上四种至少三种 不能有相同长度超2的子串重复 [输入形式] 一组或多组长度超过2的子符串.每组占一行 [ ...

  4. 记一次使用git报错,解决Unable to negotiate with **** port 22: no matching host key type found. Their offer: ssh-rsa

    windows电脑重装系统,去官网下载了最新的git安装,一路next下来,打开bash按老路子设置,生成公钥 git config --global user.name "yourname ...

  5. Java报错: A component required a bean of type 'com.sirifeng.testmybatis.mapper.BookMapper' that could not be found.

    在学习Spring-boot-mybatis时,报错A component required a bean of type 'com.sirifeng.testmybatis.mapper.BookM ...

  6. Python入门-深入了解数据类型以及方法

    写在开始:每一种数据类型,有对应一种功能,面对不同的问题,使用不同类型. 1.全部数据类型 1.2数值型:解决数字的计算问题 #基础的计算,求除结果,求商,求余数 print(10 / 3) prin ...

  7. HTTP长连接和短连接及应用情景

    HTTP短连接 HTTP/1.0中默认使用短连接, 客户端和服务器进行一次HTTP操作, 就需要建立一次连接, 任务结束连接也关闭. 当客户端浏览器访问的web网页中包含其他的web资源时, 每遇到一 ...

  8. Mybatis映射文件动态SQL语句-02

    foreach UserMapper.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYP ...

  9. mycat实现主从读取中的问题

    schema.xml 中的配置如下:..... <dataHost name="aaa" maxCon="2000" minCon="100&q ...

  10. Linux下安装Typora

    系统:Ubuntu16.0 下载链接:https://www.typora.io/#linux 参考链接:https://www.cnblogs.com/wenkangzero/p/13202415. ...