python基础之模块之序列化

---什么是序列化(picking)?

 我们把变量从内存中变成可存储或传输的过程称之为序列化。

 序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

 反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

 举例:大家应该都玩过魔兽争霸,应该知道该游戏有一个存档的功能,我每次不想玩得时候就可以存档,然后再玩得时候我们根本不需要重新开始玩,只需要读档就可以了。我们现在学习的事面向对象的思想,那么在我们眼中不管是我们的游戏角色还是游戏中的怪物、装备等等都可以看成是 一个个的对象,进行简单的分析。

角色对象(包含等级、性别、经验值、HP、MP等等属性)
武器对象(包含武器的类型、武器的伤害、武器附加的能力值等等属性)
怪物对象(包含等级、经验值、攻击、怪物类型等等)
于是玩游戏过程变的非常有意思了,创建游戏角色就好像是创建了一个角色对象,拿到武器就好像创建了一个武器对象,遇到的怪物、NPC等等都是对象了。
然后再用学
过的知识进行分析,我们发现对象的数据都是保存在内存中的,应该都知道内存的数据在断电以后是会消失的,但是我们的游戏经过存档以后,就算你关机了几天,
再进入游戏的时候,读取你的存档发现你在游戏中的一切都还在呢,奇怪了,明明内存中的数据已经没有了啊,这是为什么呢?于是再仔细考虑,电脑中有硬盘这个
东西在断电以后保存的数据是不会丢的(要是由于断电导致的硬盘损坏了,没有数据了,哈哈,不在此考虑中)。那么应该很容易的想到这些数据是被保存在硬盘中
了。没错!这就是对象的持久化,也就是我们今天要讲的对象的序列化。那么反序列化就很好理解了就是将存放在硬盘中的信息再读取出来形成对象。

---如何序列化?

  在python中提供了两个模块可进行序列化。分别是pickle和json。

pickle

  pickle是python中独有的序列化模块,所谓独有,就是指不能和其他编程语言的序列化进行交互,因为pickle将数据对象转化为bytes

>>> import pickle
>>> d=[1,2,3,4]
>>> pickle.dumps(d)
b‘\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.‘
>>> type(pickle.dumps(d))
<class ‘bytes‘>     #类型为bytes

  pickle模块提供了四个功能:dumps、dump、loads、load。

  dumps和dump都是进行序列化,而loads和load则是反序列化。

>>> import pickle
>>> d=[1,2,3,4]
>>> pickle.dumps(d)
b‘\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.‘

dumps

  dumps将所传入的变量的值序列化为一个bytes,然后,就可以将这个bytes写入磁盘或者进行传输。

  而dump则更加一步到位,在dump中可以传入两个参数,一个为需要序列化的变量,另一个为需要写入的文件。

f=open(‘file_test‘,‘wb‘)
>>> d=[1,2,3,4]
>>> pickle.dump(d,f)
>>> f.close()
>>> f=opem(‘file_test‘,‘rb‘)
 f=open(‘file_test‘,‘rb‘)
>>> f.read()
b‘\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.‘

dump

  loads当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用loads方法反序列化出对象,也可以直接用load方法直接反序列化一个文件。

>>> d=[1,2,3,4]
>>> r=pickle.dumps(d)
>>> print(r)
b‘\x80\x03]q\x00(K\x01K\x02K\x03K\x04e.‘
>>> pickle.loads(r)
[1, 2, 3, 4]

loads

>>> d=[1,2,3,4]
>>> f=open(‘file_test‘,‘wb‘)
>>> pickle.dump(d,f)
>>> f.close()
>>> f=open(‘file_test‘,‘rb‘)
>>> r=pickle.load(f)
>>> f.close()
>>> print(r)
[1, 2, 3, 4]

load

json

  如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

  如果想要详细了解JSON的话,推荐一篇博文:http://www.cnblogs.com/mcgrady/archive/2013/06/08/3127781.html

  json中的方法和pickle中差不多,也是dumps,dump,loads,load。使用上也没有什么区别,区别在于,json中的序列化后格式为字符。

>>> import json
>>> d=[1,2,3,4]
>>> json.dumps(d)
‘[1, 2, 3, 4]‘
>>> type(json.dumps(d))
<class ‘str‘>           #类型为str

因为python中一切事物皆对象,所有对象都是基于类创建的,所以,‘类’在python中占据了相当大的比重。我们能否将类的实例进行序列化呢?

>>> class student(object):
...     def __init__(self,name,age,course):
...         self.name=name
...         self.age=age
...         self.course=course
...
>>> a=student(‘linghuchong‘,24,‘xixingdafa‘)
>>> import json
>>> json.dumps(a)
TypeError: <student object at 0x035B8230> is not JSON serializable

晕,竟然不能!现在几乎都是面向对象编程,类这么重要,竟然不能序列化,怎么搞?

不要着急,前面的代码之所以无法把student类实例序列化为JSON,是因为默认情况下,dumps方法不知道如何将student实例变为一个JSON的‘{}‘对象。

我们需要’告诉‘json模块如何转换。

>>> def st_to_dict(a):
...     return {‘name‘:a.name,‘age‘:a.age,‘course‘:a.course}
...
>>> print(json.dumps(a,default=st_to_dict))          #default参数就是告知json如何进行序列化
{"course": "xixingdafa", "name": "linghuchong", "age": 24}
    

当然,如果我们每定义一个类,还得再定义一下这个类的实例转换为字典的函数实在是太麻烦了!!我们有一个一劳永逸的办法。

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

其中的__dict__不需我们在类中定义,因为通常class的实例都有一个__dict__属性,它就是一个字典,用来存储实例变量。

>>> print(a.__dict__)
{‘course‘: ‘xixingdafa‘, ‘age‘: 24, ‘name‘: ‘linghuchong‘}
时间: 2024-11-03 04:36:44

python基础之模块之序列化的相关文章

python 基础之 模块

Python 基础之模块 一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 就是一个python文件中定义好了类和方法,实现了一些功能,可以被别的python文件所调用 那么如何使用一个模块呢? 当然是使用import 模块名 这个方式加载一个模块了 ,比如:import time 如果要使用模块中的类,就是: 模块名 点儿 类 比如: import modle.Teacher 那么如果模块中的方法不知道是做什么用的怎么办呢?     两种方法:    

#python基础学习模块:marshal 对象的序列化

#标准库地址:https://docs.python.org/2/library/marshal.html"""有时候,要把内存中一个对象持久化保存磁盘或者序列化二进制流通过网络发送到远程主机上,python有很多模块提供了序列化与反列化功能,如:marshal, pickle, cPickle等 注意: marshal并不是一个通用的模块,在某些时候它是一个不被推荐使用的模块,因为使用marshal序列化的二进制数据格式还没有文档化,在不同版本的Python中,marsha

Python高手之路【七】python基础之模块

本节大纲 模块介绍 time &datetime模块 random os sys shutil json & picle shelve xml处理 yaml处理 configparser hashlib subprocess logging模块 re正则表达式 1:模块介绍 模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以

【python基础之----模块】

模块是实现某个功能的代码集合 函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块. 模块分为三种: 内置标准模块(标准库) 第三方模块(开源模块) 自定义模块 1. 自定义模块 # 单模块,且在同一目录下,建议用 import # 定义一个模块文件名字为common.py,在当前目录 def f2(): print("F2") #

python基础之模块二

六 logging模块 6.1 函数式简单配置 import logging #导入模块 logging.debug('debug message') #调试消息 logging.debug('info message') #导入消息 logging.debug('warning message') #警告消息 logging.error('error message') #错误消息 logging.critical('critical message') #严重信息 默认情况下python的l

Python基础-----logging模块

#!/usr/bin/env python#-*- coding:utf-8 -*- ########################################################################################################################################################灵活配置日志级别,日志格式,输出位置#####################################

带你学python基础:模块和包

一.什么是模块 在我们平时的开发过程中,或多或少会用到 Python 的一些内置的功能,或者说,还会用到一些第三方的库,我们用到的这些 Python 的内置的功能,和一些第三方的库,就可以说是一些模块了. 例如,我们在读写文件的时候,我们就会用到文件操作的模块os. 是不是经常遇到呢?模块,来了! 其实,每一个 Python 脚本文件都可以被当成是一个模块. 模块以磁盘文件的形式存在.当一个模块变得过大,并且驱动了太多功能的话,就应该考虑拆一些代码出来另外建一个模块. 模块里的代码可以是一段直接

python基础--导入模块

一,import的使用1, 模块就是一组功能的集合体,我们的程序可以导入模块来复用模块中的功能一个模块就是包含了一组功能的python文件,例如demo.py 可以通过import来使用这个文件定义demo模块如下 print("导入模块") num = 1000 def read1(): print('demo模块',num) def read2(): print('demo模块') read1() def change(): global num num = 0 模块中可以包含语句

python基础之模块part1

模块: 模块本质上就是一个Python程序. 所有说是对象的,一定可以通过  对象.方法  来实现某些操作. 模块种类: 内置模块 第三方模块 自定义模块 import在查找模块的顺序:内置模块---->第三方模块---->自定义模块. 后期学习网络编程(socket)跟线程进程(threading processing)的时候其实就是在学习这些模块. time: 在Python中时间也是一个类. 时间有三种类型: 时间戳:时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量