一、序列化/反序列化

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: 序列化/反序列化及对象的深拷贝/浅拷贝的更多相关文章

  1. python集合增删改查,深拷贝浅拷贝

    集合 集合是无序的,不重复的数据集合,它里面的元素是可哈希的(不可变类型),但是集合本身是不可哈希(所以集合做不了字典的键)的.以下是集合最重要的两点: 去重,把一个列表变成集合,就自动去重了. 关系 ...

  2. Python深复制浅复制or深拷贝浅拷贝

    1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.(比深拷贝更加节省内存)2. copy.deepcopy 深拷贝 拷贝对象及其子对象 用一个简单的例子说明如下: >& ...

  3. node种buffer对象数组 深拷贝浅拷贝问题

    node的一个上位机和下位机通信的转发程序,用的是udp转发. 其中在发送的时候会进行一次rc4加密数据 出现问题就在这个加密数据这一块,因为这个是升级包广播发送.提前生成了升级用的广播报文,是一个b ...

  4. PHP中对象的深拷贝与浅拷贝

    先说一下深拷贝和浅拷贝通俗理解 深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个 浅拷贝:赋值时,引用赋值,相当于取了一个别名.对其中一个修改,会影响另一个 PHP中, = ...

  5. 详述Python序列化

    一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样.很多时候我们会有这样的需求: 把内存中的各种数据类型的 ...

  6. 一个更好的C++序列化/反序列化库Kapok

    KapokFAQ1.Kapok的特点简单,易用,header-only,只需要引用Kapok.hpp即可:高效,初步测试性和messagepack相当.它是纯c++11实现,因此需要支持C++11的编 ...

  7. C#序列化与反序列化以及深拷贝浅拷贝

    基于二进制数据流的序列化和反序列化 /// <summary> /// 序列化 /// </summary> /// <typeparam name="T&qu ...

  8. python序列化对象和反序列化

    1.首先不管哪种语言都会用到序列化和反序列化的过程, 2.序列化:把对象转换为字节序列的过程称为对象的序列化:   反序列化:把对象转换为字节序列的过程称为对象的序列化. 3.序列化的作用:把对象(变 ...

  9. Python对象赋值、浅拷贝、深拷贝

    Python中,基本数据类型,理解为常见数据类型:布尔型.整型.浮点型.字符串.列表.元组.字典.集合,随语言不同而不同,但是根据在内存中存储方式的不同,区分开原子类型和容器类型. 对象赋值 对象的赋 ...

随机推荐

  1. Ex 6_18 硬币有限的兑换问题_第七次作业

    子问题定义: 定义一个二维数组b,其中b[i][j]表示前i个币种是否能兑换价格j,表示第i个币种的面值,第i个币种的使用有两种情况,若使用,则b[i][j]=b[i-1][j-],若不使用,则b[i ...

  2. 错误代码 1045 Access denied for user 'root'@'localhost' (using password:YES)

    1 前言 现象是用MySQL 5.7 Command Line Client可以使用root账号进入,但是其它navicat,phpsqladmin,mysql workbench,heidisql用 ...

  3. JavaScript中unicode编码与String互转(三种方法)

    1.引言 JS本身就支持unicode转string功能,一共有三种方式和String单个字符转unicode编码. 2.方法 //unicode转String 1. eval("'&quo ...

  4. [学习笔记]Javascript的包装对象

    例子1: var s="test"; s.len = 4; var t = s.len // t is undefined 原因是s是字符串,第二行代码,实际上是创建一个临时字符串 ...

  5. vue-router两种模式,到底什么情况下用hash,什么情况下用history模式呢?

    转:https://segmentfault.com/q/1010000010340823/a-1020000010598395 为什么要有 hash 和 history 对于 Vue 这类渐进式前端 ...

  6. OneNET麒麟座应用开发之四:数据上传测试

    已经测试过OneNET麒麟座开发板了,这次来尝试与OneNET的连接和数据上传.这也是我们测试这块开发办的主要原因,因为在十几种我们有这种将分散的采集点数据上传到后台的需求. 先看看麒麟座这块开发板, ...

  7. python接口自动化测试一:http协议

    1. http简介:http(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议 2. url详解:百度搜索的一个url地址:https://www.baidu.com/s?wd=%E ...

  8. java.lang.RuntimeException: Unable to get provider cn.jpush.android.service.DataProvider

    转自:https://blog.csdn.net/u014306335/article/details/80355169 Android Studio 3.1.2 报错: java.lang.Runt ...

  9. 不同git仓库版本控制

    场景: 我们有一个开源项目托管在github上面,现在打算在gitlab上进行私有托管开发,当适合发布一个版本的时候提交到github. Git合并特定commits 到另一个分支 实现如下: 1.获 ...

  10. BZOJ1303 [CQOI2009]中位数图 其他

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1303 题意概括 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数 ...