广告
返回顶部
首页 > 资讯 > 后端开发 > Python >python序列化:json,pickl
  • 182
分享到

python序列化:json,pickl

序列化pythonpickl 2023-01-31 01:01:17 182人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

什么是序列化,把程序中的对象或者变量,从内存中转换为可存储或可传输的过程称为序列化。在 python 中,这个过程称为 pickling,在其他语言中也被称为 serialization,marshalling,flattening 等。

什么是序列化,把程序中的对象或者变量,从内存中转换为可存储或可传输的过程称为序列化。在 python 中,这个过程称为 pickling,在其他语言中也被称为 serialization,marshalling,flattening 等。程序中的对象(或者变量)在序列化之后,就可以直接存放到存储设备上,或者直接发送到网络上进行传输。

序列化的逆向过程,即为反序列化(unpickling),就是把序列化的对象(或者变量)重新读到内存中~

JSON 模块就用于序列化和反序列化。对象(变量)使用json模块序列化后,表现为一个字符串,序列化为字符串格式的好处是:序列化后的对象可以在不同的编程语言之间传递。
 
Python 数据类型和 json 中的字符串对应关系如下:

python数据类型 json字符串
dict '{}'
list '[]'
tuple '[]'
str 'string'
int/float '1.23'
True/False true/false
None null

 
json模块常用的就4个方法:dump,dumps,load,loads~

json.dump / json.dumps

这两个方法用于序列化对象,两个方法的功能类似,区别在于,json.dumps 方法接收一个参数,即需要序列化的对象,其余参数为可选参数,方法执行完成后,会返回序列化后得到的字符串;json.dump 接收两个参数,第一个参数和 dumps方法 相同,即需要序列化的对象,第二个参数为文件对象,例如 open方法 的返回对象,其余为可选参数,方法执行后,序列化后的字符串会直接写到文件中~
 
dump / dumps 示例:

import json

d = {'name': '贝贝', 'age': 18}
lst = [1, 2, 3]
tup = ('a', 'b', 'c')
s = 'hello'
i = 3
f = 1.2
flag_1 = True
flag_2 = False
abc = None

print(type(json.dumps(d)))   # <class 'str'>
print(json.dumps(d))           # {"name": "\u8d1d\u8d1d", "age": 18}
print(json.dumps(lst))         # [1, 2, 3]
print(json.dumps(tup))        # ["a", "b", "c"]
print(json.dumps(s))           # "hello"
print(json.dumps(i))            # 3
print(json.dumps(f))            # 1.2
print(json.dumps(flag_1))   # true
print(json.dumps(flag_2))   # false
print(json.dumps(abc))       # null

# 以上的输出类型都是 class 'str' 类型,即字符串类型~

#################################
d = {'name': '贝贝', 'age': 18}
with open(file='/tmp/test_json', mode='w') as f:
    json.dump(d, f)

# 执行完成后,查看输出的文件内容:
➜  ~ cat /tmp/test_json
{"name": "\u8d1d\u8d1d", "age": 18}%   

json.load / json.loads

这两个方法用于序列化后的字符串 反序列化,两者的区别和 dump、dumps 类似,json.loads 接收一个字符串参数,其余参数为可选参数,json.load 也接收一个参数,该参数为包含 json 字符串的文件对象~

json.loads示例:

d = json.loads('{"name": "\u8d1d\u8d1d", "age": 18}')
print(type(d), '--', d)

abc = json.loads('null')
print(type(abc), '--', abc)

tup = json.loads('["a", "b", "c"]')
print(type(tup), '--', tup)

s = json.loads('"hello"')
print(type(s), '--', s)

# 输出结果:
<class 'dict'> -- {'name': '贝贝', 'age': 18}
<class 'NoneType'> -- None
<class 'list'> -- ['a', 'b', 'c']
<class 'str'> -- hello

注意:传递给 json.loads 方法的参数必须用 单引号括起来,里面的字符串使用双引号,例如不能有这样的写法:json.loads("hello"),json.loads("['a', 'b', 'c']"),json 字符串中不支持单引号~
 
json.load示例:

with open(file='/tmp/test_json', mode='r') as f:
    json_data = json.load(f)
    print(type(json_data), '--', json_data)

# 输出结果:
<class 'dict'> -- {'name': '贝贝', 'age': 18}

json模块中的字符编码问题

我们可以看到上述示例中,字典对象中包含有中文字符,在进行序列化后,不管是使用 dumps 存放到字符串中 还是使用 dump 存放到文件中,中文字符串是使用 unicode 编码格式存放的。
 
python3中,代码中的字符串都是使用 unicode 格式存放的,序列化之后也是以unicode 格式存放,所以序列化和反序列化过程都不存在问题。

 
Python2中,代码中的字符串是 str类型,str类型 和 unicode类型 的关系如下所示:

unicode -----> encode --------> str(例如为 utf-8编码)
utf-8(例如为 utf-8编码) --------> decode ----------> unicode

所以在Python2中,序列化过程和反序列化过程都有涉及到转码过程(encode和decode),序列化过程 会先将对象中的字符串 使用utf-8 进行解码(decode),转换为unicode类型后,再存放到文件或者字符串中,反序列化过程 会将 json字符串 使用utf-8 编码(encode),然后存放到内存中的变量~
 
说明:在Python2中,dumps(dump)和loads(load)默认使用 utf-8 进行 encode和decode,若要使用使用其他编码方式,可以通过 encode参数 指定;在Python3中,dumps(dump)和loads(load)方法都没有 encode参数~
 
来看如下示例:

# -*- coding:utf-8 -*-
d = {'name': '贝贝', 'age': 18}
print type(json.dumps(d)), '--', json.dumps(d)

res_d = json.loads('{"age": 18, "name": "\u8d1d\u8d1d"}')
print type(res_d), '--', res_d

# 结果输出:
<type 'str'> -- {"age": 18, "name": "\u8d1d\u8d1d"}
<type 'dict'> -- {u'age': 18, u'name': u'\u8d1d\u8d1d'}

如上过程,序列化和反序列化都没有问题,这是因为,文件的开头指定了 ‘# -- coding:utf-8 --’,程序中的字符串(str类型)就是使用utf-8编码后存放于内存中~
 
现在修改一下文件开头的编码:

# -*- coding:gbk -*-
d = {'name': '贝贝', 'age': 18}
print type(json.dumps(d)), '--', json.dumps(d)

res_d = json.loads('{"age": 18, "name": "\u8d1d\u8d1d"}')
print type(res_d), '--', res_d

这个时候就会报出如下错误信息,很简单,utf-8 无法解码 gbk编码的字符串('贝贝')

UnicodeDecodeError: 'utf8' codec can't decode byte 0xb1 in position 0: invalid start byte

解决方法就是,在 dumps 过程中指定使用 gbk 进行解码,然后输出就正常了~

# -*- coding:gbk -*-
d = {'name': '贝贝', 'age': 18}
json_str = json.dumps(d, encoding='gbk')
print type(json_str), '--', json_str

res_d = json.loads('{"age": 18, "name": "\u8d1d\u8d1d"}')
print type(res_d), '--', res_d

# 输出结果:
<type 'str'> -- {"age": 18, "name": "\u8d1d\u8d1d"}
<type 'dict'> -- {u'age': 18, u'name': u'\u8d1d\u8d1d'}

注意:这里 loads 过程不需要指定编码格式,因为反序列化之后存放到内存中的依旧是unicode格式的字符串~
 
还有一种更简单的解决方式,即在中文字符前加 u

d = {'name': u'贝贝', 'age': 18}
json_str = json.dumps(d)

pickle 模块也用于序列化和反序列化Python对象(变量),其用法和 json 模块的使用基本一致。pickle 模块 和 json 模块 区别在于:pickle 模块 仅用于Python的数据类型,序列化后的对象不能再不同的编程语言之间传递,但是 pickle 模块 可序列化几乎所有的Python数据类型,包括时间对象,函数,类…
 

序列化基本数据类型

import pickle

d = {'name': '贝贝', 'age': 18}
d_dump = pickle.dumps(d)
print(d_dump)

d_load = pickle.loads(d_dump)
print(type(d_load), '--', d_load)

# 结果输出:
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x06\x00\x00\x00\xe8\xb4\x9d\xe8\xb4\x9dq\x02X\x03\x00\x00\x00ageq\x03K\x12u.'    # 注意 输出的是 byte 类型(即python2中的str类型)
<class 'dict'> -- {'name': '贝贝', 'age': 18}

####################################
lst = [1, 2, 3]
with open('/tmp/test_pickle', mode='wb') as f:     # 打开文件的模式为二进制写
    pickle.dump(lst, f)

with open('/tmp/test_pickle', mode='rb') as f:       # 打开文件的模式为二进制读
    lst_load = pickle.load(f)
    print(type(lst_load), '--', lst_load)

# 结果输出:
<class 'list'> -- [1, 2, 3]

# 存放序列化对象的文件:
➜  ~ cat /tmp/test_pickle 
q(KKKe.% 

可以看到 pickle序列化后的数据,可读性差,不像json那样一目了然~

序列化类class对象

import pickle

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def say_hello(self):
        print('hello %s' % (self.name))

p = Person('贝贝', 18)
# p.say_hello()
# del Person

with open('/tmp/test_pickle', mode='wb') as f:
    pickle.dump(p, f)

with open('/tmp/test_pickle', mode='rb') as f:
    p_load = pickle.load(f)
    p_load.say_hello()

# 输出结果:
hello 贝贝

注意:中途不能del Person,不然会出现如下错误

_pickle.PicklingError: Can't pickle <class '__main__.Person'>: attribute lookup Person on __main__ failed

shelve 模块也用于序列化,shelve 模块是在 pickle 模块上做了一层封装,也仅支持两个Python程序之间进行交换~,优点是 shelve 模块 可以序列化 Python 的所有数据类型~
 
shelve 模块比 pickle 模块更加简单,只有一个 open函数,返回类似字典的对象,可读可写,当为某个 key 赋值时,这个值会被序列化,并进行存储;通过某个 key 读出对应的值时,即是一个反序列化过程,其中 key 必须为字符串,而值可以是python所支持的数据类型。
 
shelve 模块存取过程:

import shelve

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def say_hello(self):
        print('hello %s' % (self.name))

p = Person('贝贝', 18)
d = {'name': 'abc', 'age': 20}

f = shelve.open(r'/tmp/test_shelve')
f['d_info'] = d
f['p_info'] = p

print(f.get('d_info'))
f.get('p_info').say_hello()

f.close()

如上过程,class对象和基本数据类型会被序列化并存放在文件 '/tmp/test_shelve' 中,f.get() 取出过程即是一个反序列化过程~
 

若是一个可变对象,使用 shelve 模块序列化之后存放到文件中,然后取出(get)对可变对象进行更改,这个时候,已经改变的可变对象只是保存在内存中,不会被写入到文件中,看如下示例:

import shelve

f = shelve.open(r'/tmp/test_shelve')
f['lst_info'] = [1,2,3]

f.get('lst_info').append(4)
print(f.get('lst_info'))

# 输出结果:
[1, 2, 3]

若要进行更改需要重新写入,即重新序列化:

import shelve

f = shelve.open(r'/tmp/test_shelve')
f['lst_info'] = [1, 2, 3]

lst = f.get('lst_info')
lst.append(4)
f['lst_info'] = lst
print(f.get('lst_info'))

# 输出结果:
[1, 2, 3, 4]

或者在使用 shelve 打开文件时,设置 writeback 为True:

f = shelve.open(r'/tmp/test_shelve', writeback=True)
f['lst_info'] = [1, 2, 3]

f.get('lst_info').append(4)
print(f.get('lst_info'))

# 输出结果:
[1, 2, 3, 4]

.................^_^

--结束END--

本文标题: python序列化:json,pickl

本文链接: https://www.lsjlt.com/news/183279.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • python序列化:json,pickl
    什么是序列化,把程序中的对象或者变量,从内存中转换为可存储或可传输的过程称为序列化。在 Python 中,这个过程称为 pickling,在其他语言中也被称为 serialization,marshalling,flattening 等。...
    99+
    2023-01-31
    序列化 python pickl
  • Python json序列化
    Python内置的json模块提供了非常完善的对象到JSON格式的转换。废话不多说,我们先看看如何把Python对象变成一个JSON: d = dict(name='Kaven', age=17, sex='Male') print(j...
    99+
    2023-01-31
    序列化 Python json
  • Python 序列化模块(json,pi
    json模块 JSON (JavaScript Object Notation):是一个轻量级的数据交换格式模块,受javascript对象文本语法启发,但不属于JavaScript的子集。 常用方法: dump(obj,fp):将对象以...
    99+
    2023-01-30
    模块 序列化 Python
  • Python的pickle序列化和JSON序列化实例分析
    本文小编为大家详细介绍“Python的pickle序列化和JSON序列化实例分析”,内容详细,步骤清晰,细节处理妥当,希望这篇“Python的pickle序列化和JSON序列化实例分析”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-06-30
  • 协议,序列化,反序列化,Json
    文章目录 协议序列化和反序列化网络计算器protocol.hppServer.hppServer.ccClient.hppClient.cclog.txt通过结果再次理解通信过程 Json...
    99+
    2023-09-01
    json 网络 服务器
  • Python序列化模块JSON与Pickle
    序列化把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flat...
    99+
    2022-11-11
  • python Json与pickle数据序列化
    在程序运行的过程中,所有的变量都是在内存中。一旦程序结束,变量所占用的内存就被操作系统全部回收。为了避免数据丢失,把变量从内存中变成可存储或传输的过程称之为序列化序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过...
    99+
    2023-01-30
    序列化 数据 python
  • python中json序列化的东东
    之所以写这个因为自己总是弄混了,容易弄错,记下来有事没事看看   序列化是指把变量从内存中变成可存储或传输的过程称之为序列化用(使用dump或者dumps),把变量内容从序列化的对象重新读到 内存里称之为反序列化(使用load或者load...
    99+
    2023-01-30
    序列化 python json
  • 怎么在python中序列化JSON
    今天就跟大家聊聊有关怎么在python中序列化JSON,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Python的优点有哪些1、简单易用,与C/C++、Java、C# 等传统语言相比...
    99+
    2023-06-14
  • Python常用标准库详解(pickle序列化和JSON序列化)
    目录常用的标准库序列化模块序列化和反序列化使用场景dumps & loadsdump & loadJSON序列化模块使用场景支持的数据类型JSON和pickle的区别...
    99+
    2022-11-11
  • 协议定制 + Json序列化反序列化
    文章目录 协议定制 + Json序列化反序列化1. 再谈 "协议"1.1 结构化数据1.2 序列化和反序列化 2. 网络版计算器2.1 服务端2.2 协议定制(1) 网络发送和读取的正确...
    99+
    2023-10-03
    网络 linux
  • Python 对象序列化与反序列化之pickle json详细解析
    目录引言picklejson尾语引言 将对象的状态信息转换为可以存储或传输的形式的过程叫作序列化 类似地从序列化后的数据转换成相对应的对象叫作 反序列化 本文介绍 Python 将对...
    99+
    2022-11-12
  • C#对Json进行序列化和反序列化
    一、Json简介 Json(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JS的一个子集。 Json采用完全独立于语言的文本格式。这使得J...
    99+
    2022-11-13
  • SpringBoot之Json的序列化和反序列化问题
    目录控制json序列化/反序列化1. @JsonIgnoreProperties的用法2. @JsonProperty 注解3. @JsonCreator 注解4. @JsonSet...
    99+
    2022-11-13
  • 详解Python之数据序列化(json、pickle、shelve)
    一、前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样。很多时候我们会有这样的需求: 把内存中的各种数据类型的...
    99+
    2022-06-04
    详解 序列化 数据
  • 在Python 中将类对象序列化为JSON
    目录1. 引言2. 举个栗子3. 解决方案3.1 使用 json.dumps() 和 __dict__3.2 实现 __str__ 和 __repr__3.3 实现 JSON enc...
    99+
    2022-11-10
  • Python序列化模块之pickle与json详解
    目录序列化模块序列化和反序列化使用场景dumps & loadsdump & loadJSON序列化模块使用场景支持的数据类型JSON和pickle的区别序列化函数j...
    99+
    2022-11-11
  • C#如何对Json进行序列化和反序列化
    这篇“C#如何对Json进行序列化和反序列化”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C#如何对Json进行序列化和反序...
    99+
    2023-06-30
  • JavaScript中怎么用JSON来序列化与反序列化
    小编给大家分享一下JavaScript中怎么用JSON来序列化与反序列化,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!用JSON...
    99+
    2022-10-19
  • Golang中Json的序列化和反序列化的使用
    目录 JSON:创建格式:基本数据类型序列化:map序列化:切片序列化:反序列化为结构体:反序列化为map:反序列化为切片: JSON: JSON(JavaScr...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作