05-3 | 序列化与反序列化 pickle ,JSON

逸兴
逸兴
逸兴
57
文章
25
评论
2020-04-2313:48:481 3682字阅读12分16秒

字节序列化

操作系统中,进程间通信(不共享内存情况下)传递的是二进制数据,进程A要和进程B通行首先进程A需要将内存中的数据转换成二进制,传递给进程B。进程B收到后需要将二进制数据转换成原类型,保存到内存中。

在这个过程中,将内存中数据结构存储下来转换成一个个字节的过程为序列化。

将一个个字节恢复成内存中对象,并且还是原来的类型, 为反序列化。

需要注意的是,序列化与反序列化前后,数据类型应该对等。比如将一个“列表”序列化后发给进程B,B收到后需要经二进制数据反序列化为“列表”。
跨进程通行必须进行数据的序列化与反序列化。

序列化:对象--->bytes

反序列化:bytes---> 对象

pickle

写在前面:

pickle其实就四个方法:

  1. pickle.dump(obj, file) 将内存对象 dump到文件中 ---持久化
  2. pickle.dumps(obj) 将内存对象dump到内存中 一般用于网络传输,不需要持久化因为直接发送了
  3. pickle.load(file) 从文件中反序列化;
  4. pickle.loads(bytes) 从bytes对象中反序列化

python中可通过pickle实现序列化与反序列化

pickle只是遵循序列化协议, 实现序列化与反序列化的一种方法, 此外还有很多方式。

pickle.dump() 序列化

pickle.dump(obj, file) 将对象序列化并保存文件中。

pickle.dumps(obj) 将对象dump到内存中, 并不写文件。

把内存中的数据存储下来, 转变成一个个字节。

序列化后保存到磁盘中是为持久化。

序列化后可以进行跨进程通信, 或者网络传输。, 对方收到后再进行反序列化。

# encoding = utf-8
__author__ = "hugbg.com"

import pickle

filename = "pickle.txt"
a = '1'
b = 1
c = ['aaa', 127]

x = pickle.dumps(a)
print(type(x), x)   # dumps 到内存,是bytes 类型

with open(filename, 'wb') as f:    # 要以二进制打开文件(序列化后就是二进制的)
    pickle.dump(a, f)   # 将内存对象序列化,并dump 到文件。序列化的持久化
    pickle.dump(b, f)
    pickle.dump(c, f)

序列化的文件:

05-3 | 序列化与反序列化 pickle ,JSON

以十六进制查看:

05-3 | 序列化与反序列化 pickle ,JSON

pickle.load() 反序列化

pickle.load(file) 从文件中反序列化;

pickle.loads(bytes) 从bytes对象中反序列化;

# encoding = utf-8
__author__ = "hugbg.com"

import pickle

filename = "pickle.txt"
a = '1'
b = 1
c = ['aaa', 127]

x = pickle.dumps(a)
print(type(x), x)   # dumps 到内存,是bytes 类型

# with open(filename, 'wb') as f:
#     pickle.dump(a, f)   # dump 到文件
#     pickle.dump(b, f)
#     pickle.dump(c, f)

print(pickle.loads(x))     # 从字节对象读取

with open(filename, 'rb') as f:
    for i in range(3):
        y = pickle.load(f)   # 从文件读
        print(type(y), y)
05-3 | 序列化与反序列化 pickle ,JSON

pickle 是带类型进行序列化的。

pickle是python专用的,此外还有通用的序列化与反序列化的库protocal buffer, msgpack 等。

强烈建议使用msgpack,可以压缩,效率更高。https://msgpack.org, 其方法和语法与pickle 相同,跨语言,效率高,使用简单。

json文本序列化

JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript
1999年ES3 的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。
http://json.org/
https://www.json.org/json-zh.html

使用方法与pickle 相同,语法一致。

JSON的数据类型

05-3 | 序列化与反序列化 pickle ,JSON
  • 字符串
    • 必须用双引号包围起来的任意字符的组合,可以有转义字符。
  • 数值
    • 有正负,有整数、浮点数
  • 对象
    • 无序的键值对的集合 {“k”: v}
      • key 必须是字符串
      • value 可以是 字符串,数值,对象,任意合法值
    • 空集合 {}
  • 数组
    • 有序的值的集合,列表
    • 格式[val1, ..., valn]
    • 空数组 []

实例:

05-3 | 序列化与反序列化 pickle ,JSON

json 是纯文本类型。

json.dump()

# encoding = utf-8
__author__ = "hugbg.com"

import json

filename = 'test.json'

direct = {
    'name': 'Tom',
    'age': 21,
    'like': ['read', 'games', 1, '1'],
    'family': ('jeery', 'mike', 'marry'),
    'student': False,
    'work': None
}

d1 = json.dumps(direct)     # dump 到内存
print(type(d1), d1)   # 字符串类型,元组 会被转成 列表, 同时 False, None 会被映射

with open(filename, 'w', encoding='utf-8') as f:
    json.dump(direct, f)
05-3 | 序列化与反序列化 pickle ,JSON
05-3 | 序列化与反序列化 pickle ,JSON

从上面可以看出,python到json会做一定数据类型的转换

python 支持少量数据类型到json类型的转换

python类型json类型
Truetrue
Falsefalse
Nonenull
strstring
intinteger
floatfloat
listarray
directobject

json.load()

# encoding = utf-8
__author__ = "hugbg.com"

import json

filename = 'test.json'

direct = {
    'name': 'Tom',
    'age': 21,
    'like': ['read', 'games', 1, '1'],
    'family': ('jeery', 'mike', 'marry'),
    'student': False,
    'work': None
}

d1 = json.dumps(direct)     # dump 到内存
print(type(d1), d1)   # 字符串类型,元组 会被转成 列表, 同时 False, None 会被映射

with open(filename, 'w', encoding='utf-8') as f:
    json.dump(direct, f)

with open(filename, 'r', encoding='utf-8') as f:
    l1 = json.load(f)   # 反序列化数据
    print(type(l1), l1)     # 保持原数据类型不变, 元组会被转换为 列表

print(l1 == direct)

msgpack

msgpack.dump()

msgpack.dumps()

msgpack.load()

msgpack.loads()

练习:将ini配置文件格式转换为json

[DEFAULT]
name = test

[mysqld]
port = 3306
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock

[mysql]
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
testbl = True

[mysqldump]
max_allowed_packet = 2M
# encoding = utf-8
__author__ = "hugbg.com"

from configparser import ConfigParser
import json

# 将my.ini 转换成json格式

s_file = "my.ini"
d_file = "my.json"

cfg = ConfigParser()
cfg.read(s_file)


def get_section():
    """
    将所有section 转换为字典
    :return: dict_list, section 与 option value的嵌套结构
    """
    dict_list = {}
    for section in cfg.sections():
        dict_list[section] = {}
        for i in cfg.options(section):
            dict_list[section][i] = cfg.get(section, i)
    return dict_list


def to_json(list):
    """
    json 序列化
    :param list: ini 转换后的 字典数据
    :return:
    """
    with open(d_file, 'w', encoding='utf-8') as f:
        json.dump(list, f)


if __name__ == "__main__":
    to_json(get_section())



https://www.hugbg.com/archives/2370.html
逸兴
  • 本文由 发表于 2020-04-2313:48:48
  • 除非特殊声明,本站文章均为原创,转载请务必保留本文链接
01-1 数据类型 基础语法

01-1 数据类型

第一章 数据类型 使用type() 函数可以查看数据类型 1.1 字符串 str 字符串是使用单引号或双引号括起来的任意文本。 比如'abc', '123'等 字符串类型 字符串类型用str表示 st...
09-5 | asyncio基本使用 并发编程

09-5 | asyncio基本使用

第一节 关于asyncio asyncio 在3.4 版本中加入到标准库, asyncio基于selector实现, 看似库, 其实是个框架, 包含异步IO, 事件循环, 协程, 任务等内容。 通过a...
09-4 | 全局解释器锁 & 多进程 & 池 并发编程

09-4 | 全局解释器锁 & 多进程 & 池

GIL CPython 在解释器进程级别有一把锁,叫做GIL,即全局解释器锁。 GIL 保证CPython进程中,只有一个线程执行字节码。甚至是在多核CPU的情况下,也只允许同时只能 有一个CPU核心...
匿名

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

评论:1   其中:访客  1   博主  0
    • 浮光 浮光

      入我相思门,知我相思苦。 —三五七言 / 秋风词