博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python IO编程-序列化
阅读量:6736 次
发布时间:2019-06-25

本文共 3262 字,大约阅读时间需要 10 分钟。

原文链接:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143192607210600a668b5112e4a979dd20e4661cc9c97000

在程序运行的过程中,所有变量的数据都是储存在内存中,随着程序的关闭,数据随即消失,变量所占用的内存就会被系统收回。我们把数据从内存中变成可存储或传输的的过程,就称为序列化。序列化之后,就可以把序列化的内容进行存储或者通过网络传输。反之,将变量内容从序列化对象重新读取到内从中,被称为反序列化。

在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等

 

磁盘

python中提供了pickle模块来实现序列化

序列化:

 pickle.dumps(d) 将任意对象d序列化称为 bytes ,然后就可以将这个 bytes 写入到一个文件。 pickle.dump(d,f) (f要先open)直接将任意对象 d 序列化然后写入到一个 file-like Object :

反序列化:

当我们想要将变量内容从序列化对象读取到内存中,可以使用把序列化对象读取到一个bytes,然后在用 pickle.loads(bytes) 反序列化出对象, pickle.load(f) 直接从文件f(需要先open)反序列化对象

Pickle的问题和所有其他编程语言特有的序列化问题一样,就是它只能用于Python,并且可能不同版本的Python彼此都不兼容,因此,只能用Pickle保存那些不重要的数据,不能成功地反序列化也没关系。

 

JSON

如果我们需要在不同编程语言中间传递数据,就必须将数据序列化为标准格式,如XML,但是更好的解决办法是JSON,因为JSON表示出来就是字符串,可以被所有语言读取,也可以方便的进行储存或者网络传输。JSON不仅是标准格式,而且比XML更快,并且能直接在Web页面中读取,非常方便

JSON对象表示的就是标准的JavaScript语言的对象,JSON对象和python语言内置数据类型对应如下:

JSON类型 Python类型
{} dict
[] list
"string" str
1234.56 int或float
true/false True/False
null None

Python中内置的 json 模块提供了非常方便的python类型到JSON格式的转换

 json.dumps(d) 将任意对象序列化为JSON对象,返回一个 str ,内容就是标准的JSON,类似磁盘序列化, dumps() 方法可以将序列化内容写入一个 file-like Object 

 loads() 和 load() 是 json 模块里的方法,前者把JSON的字符串反序列化,后者从 file-like Object  中读取字符串进行反序列化

由于JSON标准规定JSON编码是 UTF-8 ,所以我们总是能正确地在Python的 str 与JSON的字符串之间转换。

 

JSON进阶

python 的 dict 对象可以序列化为JSON的 {} ,不过我们更喜欢使用一个类 class 来表示对象,比如定义一个 student 类,然后进行序列化

import jsonclass Student(object):    def __init__(self, name, age, score):        self.name = name        self.age = age        self.score = scores = Student('Bob', 20, 88)print(json.dumps(s))

运行代码,肯定会出现一个 TypeError :

Traceback (most recent call last):  ...TypeError: <__main__.Student object at 0x10603cc50> is not JSON serializable

错误的原因是 Student 对象不是一个可序列化为JSON的对象。

别急,我们仔细看看 dumps() 方法的参数列表,可以发现,除了第一个必须的 obj 参数外, dumps() 方法还提供了一大堆的可选参数:

这些可选参数就是让我们来定制JSON序列化。前面的代码之所以无法把 Student 类实例序列化为JSON,是因为默认情况下, dumps() 方法不知道如何将 Student 实例变为一个JSON的 {} 对象。可选参数 default (像是一个修饰器,会对传入的序列换对象先处理)就是把任意一个对象变成一个可序列为JSON的对象(上面表格里的),我们只需要为Student专门写一个转换函数,再把函数传进去即可:(default在下面)

def student2dict(std):    return {        'name': std.name,        'age': std.age,        'score': std.score    }

这样, Student 实例首先被 student2dict() 函数转换成 dict ,然后再被顺利序列化为JSON:

>>> print(json.dumps(s, default=student2dict)){"age": 20, "name": "Bob", "score": 88}

不过,下次如果遇到一个 Teacher 类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意 class 的实例变为 dict :

print(json.dumps(s, default=lambda obj: obj.__dict__))

  

因为通常 class 的实例都有一个 __dict__ 属性,它就是一个 dict ,用来存储实例变量。也有少数例外,比如定义了 __slots__ 的class。

 

反序列化:

同样的道理,如果我们要把JSON反序列化为一个 Student 对象实例, loads() 方法首先转换出一个 dict 对象,然后,我们传入的 object_hook (和前面default类似)函数负责把 dict 转换为 Student 实例:

>>> def dict2student(d):             return Student(d['name'], d['age'], d['score'])>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'>>> print(json.loads(json_str, object_hook=dict2student))<__main__.Student object at 0x10cd3c190>#打印出的是反序列化的Student实例对象。

对中文进行JSON序列化时, json.dumps() 提供了一个 ensure_ascii 参数,该参数值为True会将中文变为ASCII码?为False则还是中文

# -*- coding: utf-8 -*-import jsonobj = dict(name='小明', age=20)s = json.dumps(obj,ensure_ascii=False)print(s)#结果{"name": "小明", "age": 20} #为True结果{"name": "\u5c0f\u660e", "age": 20}

  

转载于:https://www.cnblogs.com/Gaoqiking/p/10571600.html

你可能感兴趣的文章
Win7环境下VS2010配置Cocos2d-x-2.1.4最新版本的开发环境(转载)
查看>>
RPi 2B Documentation
查看>>
ReSharper2017.3的列对齐、排版格式、列对齐错误的修复
查看>>
常用的JavaScript模式
查看>>
夹角有多大(题目已修改,注意读题)
查看>>
前景窗口 活动窗口 焦点窗口的区别及设置
查看>>
思科模拟器——使用路由器分割局域网
查看>>
全面了解安装使用Linux下的日志文件系统
查看>>
iOS bug 之 H5 页面没有弹出提示框
查看>>
switch case语句
查看>>
ORACLE SQL语句优化技术分析
查看>>
iOS中Bitcode的介绍及配置
查看>>
正则表达式(应用)
查看>>
NSOperation与performSelectorOnMainThread
查看>>
array
查看>>
POJ 2376 Cleaning Shifts 贪心
查看>>
Python3学习笔记-发送邮件
查看>>
实例介绍PDU申请流程
查看>>
在JScript中使用正则表达式
查看>>
HTML多选操作的实现
查看>>