python: 序列化/反序列化及对象的深拷贝/浅拷贝
一、序列化/反序列化
python中内置了很多序列化/反序列化的方式,最常用的有json、pickle、marshal这三种,示例用法如下:
import json
import pickle
import marshal author1 = {"name": "菩提树下的杨过", "blog": "http://yjmyzz.cnblogs.com/", "title": "架构师", "pets": ["dog", "cat"]} # json序列化
json_str = json.dumps(author1)
print("json=>\n", json_str) # json字符串反序列化
author2 = json.loads(json_str) # pickle序列化
pickle_str = pickle.dumps(author1)
print("pickle=>\n", pickle_str) # pickle字符串反序列化
author3 = pickle.loads(pickle_str) # marshal序列化
marshal_str = marshal.dumps(author1)
print("marshal=>\n", marshal_str) # marshal反序列化
author4 = marshal.loads(marshal_str) print("\n",
id(author1), "\n",
id(author2), "\n",
id(author3), "\n",
id(author4), "\n",
author1, "\n",
author2, "\n",
author3, "\n",
author4) with open("json.txt", "w") as file1:
json.dump(author1, file1) with open("pickle.txt", "wb") as file2:
pickle.dump(author1, file2) with open("marshal.txt", "wb") as file3:
marshal.dump(author1, file3)
输出:
json=>
{"name": "\u83e9\u63d0\u6811\u4e0b\u7684\u6768\u8fc7", "blog": "http://yjmyzz.cnblogs.com/", "title": "\u67b6\u6784\u5e08", "pets": ["dog", "cat"]}
pickle=>
b'\x80\x03}q\x00(X\x04\x00\x00\x00nameq\x01X\x15\x00\x00\x00\xe8\x8f\xa9\xe6\x8f\x90\xe6\xa0\x91\xe4\xb8\x8b\xe7\x9a\x84\xe6\x9d\xa8\xe8\xbf\x87q\x02X\x04\x00\x00\x00blogq\x03X\x1a\x00\x00\x00http://yjmyzz.cnblogs.com/q\x04X\x05\x00\x00\x00titleq\x05X\t\x00\x00\x00\xe6\x9e\xb6\xe6\x9e\x84\xe5\xb8\x88q\x06X\x04\x00\x00\x00petsq\x07]q\x08(X\x03\x00\x00\x00dogq\tX\x03\x00\x00\x00catq\neu.'
marshal=>
b'\xfb\xda\x04name\xf5\x15\x00\x00\x00\xe8\x8f\xa9\xe6\x8f\x90\xe6\xa0\x91\xe4\xb8\x8b\xe7\x9a\x84\xe6\x9d\xa8\xe8\xbf\x87\xda\x04blog\xfa\x1ahttp://yjmyzz.cnblogs.com/\xda\x05title\xf5\t\x00\x00\x00\xe6\x9e\xb6\xe6\x9e\x84\xe5\xb8\x88\xda\x04pets[\x02\x00\x00\x00\xda\x03dog\xda\x03cat0' 4307564944
4309277360
4307565016
4309277432
{'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']}
{'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']}
{'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']}
{'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']}
注:api的方法名还是很好记的,dump/dumps意为“倒垃圾”,把对象向xxx里一倒,就算序列化完成了。反之load/loads即从字符串或文件中装载(还原)对象。特别要值得一提的是:pickle、marshal存在安全问题,如果装载的字符串或文件里,包含有精心设计的恶意代码,会让恶意代码执行(关于反序列化的漏洞,大家可以上网查一下,有很多类似的介绍)。另外从序列化后的字符串大小来看,默认情况下,就本示例而言,json序列化后的字符串长度最小,so,综合来看,推荐同学们使用json序列化/反序列化。
二、深拷贝、浅拷贝
import copy
list_1 = [1, 2, 3, [4, 5]]
list_2 = copy.copy(list_1) # 浅拷贝
list_3 = copy.deepcopy(list_1) # 深拷贝
list_2[3][0] = 99
print("\n", list_1, "\n", list_2, "\n", list_3)
list_3[3][1] = 100
print("\n", list_1, "\n", list_2, "\n", list_3)
输出:
[1, 2, 3, [99, 5]]
[1, 2, 3, [99, 5]]
[1, 2, 3, [4, 5]] [1, 2, 3, [99, 5]]
[1, 2, 3, [99, 5]]
[1, 2, 3, [4, 100]]
当一个对象里的子元素本身也是复杂元素时,浅拷贝不会为这种复杂的子元素生成全新的实例,但深拷贝可以。下面的内存分布示意图有助于大家理解:

list_2是list_1浅拷贝生成的对象,对于第4个元素,都是指向同一个列表[4,5],所以list_2修改了[4,5]中的第1个元素为99后,list_1也受到影响。list_3则是深拷贝的结果,所有元素都是独立的新实例,因此修改list_3里的任何元素,都不会影响list_1、list_2
参考文档:
1. https://docs.python.org/3/library/pickle.html
2. https://docs.python.org/3/library/json.html
3. https://docs.python.org/3/library/marshal.html
4. https://docs.python.org/3/library/copy.html
python: 序列化/反序列化及对象的深拷贝/浅拷贝的更多相关文章
- python集合增删改查,深拷贝浅拷贝
集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...
- Python深复制浅复制or深拷贝浅拷贝
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.(比深拷贝更加节省内存)2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >& ...
- node种buffer对象数组 深拷贝浅拷贝问题
node的一个上位机和下位机通信的转发程序,用的是udp转发. 其中在发送的时候会进行一次rc4加密数据 出现问题就在这个加密数据这一块,因为这个是升级包广播发送.提前生成了升级用的广播报文,是一个b ...
- PHP中对象的深拷贝与浅拷贝
先说一下深拷贝和浅拷贝通俗理解 深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 浅拷贝:赋值时,引用赋值,相当于取了一个别名.对其中一个修改,会影响另一个 PHP中, = ...
- 详述Python序列化
一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样.很多时候我们会有这样的需求: 把内存中的各种数据类型的 ...
- 一个更好的C++序列化/反序列化库Kapok
KapokFAQ1.Kapok的特点简单,易用,header-only,只需要引用Kapok.hpp即可:高效,初步测试性和messagepack相当.它是纯c++11实现,因此需要支持C++11的编 ...
- C#序列化与反序列化以及深拷贝浅拷贝
基于二进制数据流的序列化和反序列化 /// <summary> /// 序列化 /// </summary> /// <typeparam name="T&qu ...
- python序列化对象和反序列化
1.首先不管哪种语言都会用到序列化和反序列化的过程, 2.序列化:把对象转换为字节序列的过程称为对象的序列化: 反序列化:把对象转换为字节序列的过程称为对象的序列化. 3.序列化的作用:把对象(变 ...
- Python对象赋值、浅拷贝、深拷贝
Python中,基本数据类型,理解为常见数据类型:布尔型.整型.浮点型.字符串.列表.元组.字典.集合,随语言不同而不同,但是根据在内存中存储方式的不同,区分开原子类型和容器类型. 对象赋值 对象的赋 ...
随机推荐
- expdp和impdp快速导出导入,不用创建虚拟目录
expdp 和impdp不用创建虚拟目录:在cmd直接 expdp 用户名/密码 回车 就导出了,(如果提示输入用户名和密码就输入).再将导出的文件放在oracle默认的dpdump文件夹里面,然 ...
- X-Forwarded-For 的一些理解
X-Forwarded-For 是一个 HTTP 扩展头部, 主要是为了让 Web 服务器获取访问用户的真实 IP 地址(其实这个真实未必是真实的,后面会说到). 那为什么 Web 服务器只有通过 X ...
- Pandas详解一
pandas简介 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的.Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具.pandas提 ...
- 求阶乘的和(for循环)
第二种方法:
- OneNET麒麟座应用开发之二:串口读取PM25传感器数据
作为环境数据监测站首先要获取大气中可吸入颗粒物的数据.为了检测PM25数据,我们采用北京海联信为的HLPM025K3型号传感器,该传感器使用激光法测量PM25和PM10的数据. 该型传感器的检测对象如 ...
- java多线程快速入门(十三)
死锁产生的原因(必须有两个线程.必须有多个锁.锁之间必须有引用的过程) package com.cppdy; class MyThread9 implements Runnable { private ...
- python接口自动化测试一:http协议
1. http简介:http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议 2. url详解:百度搜索的一个url地址:https://www.baidu.com/s?wd=%E ...
- Jmeter录制浏览器并回放
确认证书 1.查看证书 进入Jmeter安装目录下的bin,找到ApacheJMeterTemporaryRootCA.crt 证书文件(如jmeter在安装目录中未找到,可尝试先执行下面的开始录制步 ...
- 在php中调用以及编写接口(转)
如: http://localhost/openUser.php?act=get_user_list&type=json 在这里openUser.php相当于一个接口,其中get_user_l ...
- ireport 添加行自增序号
ireport 添加行自增序号 在ireport报表中加入行的自增序号方法: 添加一个变量,如变量名为 index: 设置变量类型为Integer,计算类型为count:变量表达式为$V{index} ...