Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
目录
Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化
Python第三天 序列 5种数据类型 数值 字符串 列表 元组 字典
Python第四天 流程控制 if else条件判断 for循环 while循环
Python第五天 文件访问 for循环访问文件 while循环访问文件 字符串的startswith函数和split函数
Python第七天 函数 函数参数 函数变量 函数返回值 多类型传值 冗余参数 函数递归调用 匿名函数 内置函数 列表表达式/列表重写
Python第八天 模块 包 全局变量和内置变量__name__ Python path
Python第九天 面向对象 类定义 类的属性 类的方法 内部类 垃圾回收机制 类的继承 装饰器
Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 标准错误 重定向 输出流和输入流
Python第十二天 收集主机信息 正则表达式 无名分组 有名分组
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
Python第十五天 datetime模块 time模块 thread模块 threading模块 Queue队列模块 multiprocessing模块 paramiko模块 fabric模块
python中的任何数据类型都可以dump成json格式
https://www.birdpython.com/posts/2/47/
简单序列化
序列化
将对象的状态信息转换为可以存储或传输的形式的过程
不但读写磁盘需要通过文件对象,网络传输数据也需要通过文件对象,因为网络 IO 是指通过文件对象去读写网卡而已,磁盘 IO 是指通过文件对象读写磁盘而已。我们知道文件对象只能处理字符流,如果我们想把非字符类型数据(int,float,bool,list,tuple,dict等等)通过网络发到其他机器或保存到本地文件,那就需要序列化
把变量从内存中变成可存储或传输的过程(也就是变成字符流的过程)
把序列化后的字符流还原成序列化之前的类型数据的过程叫反序列化
最典型场景是
1、很多游戏允许你在退出的时候保存进度,序列化到磁盘,然后你再次启动的时候反序列化回到上次退出的地方
2、序列化为json,在网络上传输
常用的一些序列化
pickle、cPickle 这两个模块用法差不多,cpickle模块,C语言实现,速度是pickle的1000倍,可以先尝试导入cpickle不行再导入pickle
JSON
Shelve
YAML
pickle模块
所有python支持的类型都可以用pickle做序列化
dump(obj, file, protocol=None)
obj:表示序列化的对象,处理循环,递归引用对象,类,函数,类的实例
file:支持write()方法的文件句柄,可以是真实文件,也可以StringIO对象
protocol:序列化协议,0表示ascii协议,ascii码表示,1表示老的二进制协议,2表示新二进制协议,默认为0
pickle的方法
dump保存到磁盘
dumps保存到内存
load 读到磁盘
loads 读到内存
try:
import cPickle as pickle
except ImportError:
import pickle mylist = [1, True, "hello"]
seqdata = pickle.dumps(mylist) # 序列化成字符流
print(type(seqdata)) # list 类型数据 序列化成 str 类型
print(seqdata) # 序列化后的字符流 mylistreseq = pickle.loads(seqdata) # 把被序列化的字符流反序列化成 list
print(type(mylistreseq)) # list 类型
print(mylistreseq) # 反序列化后的 list
在 Python 3 中,把用 pickle 序列化后的字符流存储到磁盘,必须以 wb 的形式;同样,从磁盘上读取用 pickle 序列化后的字符流用 rb 的形式。
try:
import cPickle as pickle
except ImportError:
import pickle mylist = [1, True, ("hello", None)]
f = open("d:/test.txt", "wb")
seqdata = pickle.dumps(mylist) # 序列化成字符流
f.write(seqdata)
f.close() f = open("d:/test.txt", "rb")
seqdata = f.read()
f.close()
mylistreseq = pickle.loads(seqdata) # 反序列化后的 list
print(mylistreseq)
对于我们自定义类型,同样可以使用 pickle 进行序列化。
try:
import cPickle as pickle
except ImportError:
import pickle class myclass(object):
def __init__(self):
self.data = 250 def func(self):
print("ok") myobject = myclass()
xx = pickle.dumps(myobject) yy = pickle.loads(xx)
print(yy.data)
yy.func()
json模块
序列化对象供其他语言读写
JavaScript Object Notation
Json是被设计为跨语言使用的
Json是字符串格式
默认utf-8方式存储
这个模块可以把不同语言的数据类型序列化成统一的数据类型,然后反序列成相应语言的数据类型, 这个模块就是 json 模块,json 就如英文一样,如果中文和日文需要交流,可以先翻译成英文,然后在翻译成自己的语言
javascript,json的key必须用用双引号引住字符串,不能用单引号
json序列化
json.dump() 其他格式数据转为json到磁盘
json.dumps() 其他格式数据转为json到内存
ensure_ascii=True:json只能ascii编码,同样,pickle模块的dump(obj, file, protocol=None),protocol:序列化协议,0表示ascii协议,ascii码表示,默认为0
indent:缩进,让打印出来的json字符串更好看print json.dumps(data, indent=2)
encoding='utf-8':默认utf-8编码,utf-8传进来-》ascii
default :自定义类json序列化时的处理函数
def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
encoding='utf-8', default=None, sort_keys=False, **kw):
json.load() 从磁盘读json转为其他格式数据
json.loads() 从内存读json转为其他格式数据
encoding=None:load方法可能无法处理中文字符,需要通过encoding参数指定字符编码,如果dumps()方法encoding时候的不是utf-8,需要指定一下编码
object_hook:自定义类反序列化时候的处理函数
def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
parse_int=None, parse_constant=None, object_pairs_hook=None, **kw):
数据保存至JSON文件
import json # 序列化
d = {}
d['a'] = 'a'
d['b'] = 235
d['c'] = ('c1', 'c2')
d['d'] = True
d['e'] = None
with open('/tmp/d.json', mode='w') as fd:
json.dump(d, fd)
反序列化
with open('/tmp/d.json') as fd:
d1 = json.load(fd)
传递json格式的数据
定义url和方法
def collectjson(req):
if req.POST:
jsonobj = json.loads(req.body)
host = Host()
host.hostname = jsonobj['hostname']
host.vendor = jsonobj['vendor']
host.product = jsonobj['product']
host.save()
json 肯定只能支持所有语言都共有的数据类型,比如 int,float,bool 等这些类型,但是并不是所有语言的类型都是一样的,比如 Python 的 set 类型在其它语言中就没有,json 就不会支持对这种类型数据的序列化和反序列化。
import json myset = set([3, 4, 5])
data = json.dumps(myset) # 错误
Python 中的 tuple 类型在其它语言中也没有,但是 tuple 类型和 list 类型很相似,所以 json 会把 tuple 类型数据序列化和反序列化成 Python 的 list 类型数据。 如果是用其它语言进行反序列化我们序列化好的 Python 中的 tuple 类型数据,则会反序列化成其它语言对应的数组类型。
import json mytuple = (1, 2, 4)
data = json.dumps(mytuple)
dd = json.loads(data)
print(type(dd)) # <type 'list'>
print(dd) # [1, 2, 4]
Python 中的 dict 类型在其它语言中有类似的类型,比如 C++ 中的 map,Js 中的 object 等等,但是他们的格式有些不同,比如 C++ 中的 map 的键只允许字符串类型等等。我们用 json 序列化和反序列化 Python 的 dict 类型数据,就会只支持键为字符串的 dict,如果键是其它基本数据类型 json 模块会把他转为相应的字符串,如果是 tuple 类型则会报错。
import json seqdata = json.dumps({1: 1, 1.1: 2, "a": 3, None: 4, True: 5}) # 序列化成字符流,并且对不是字符串类型的键做强制转换
dd = json.loads(seqdata)
print(dd) # {u'a': 3, u'1': 5, u'null': 4, u'1.1': 2} seqdata = json.dumps({(1,2): 1}) # 虽然字典本身没问题,但是使用 json 序列化会报错
Python 的数据类型对应的 json 数据类型的关系图,当然其它语言的数据类型也对应这同样的 json 数据类型
我们自定义的类对象是否可以用 json 序列化呢,比如我们定义一个 Human 类,然后对 Human 类的对象进行序列化
import json class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex oneman = Human('如花', 18, "女")
seqdata = json.dumps(oneman) # 抛出异常,...is not JSON serializable
上面的代码之所以无法把 Human 类对象序列化为 json,是因为默认情况下,json 模块中的 dumps 函数不知道如何将 Human 对象变为一个 json 对象。 dumps 函数的可选参数 default 就是把任意一个对象变成一个可序列为 json 的对象,我们只需要为 Human 类专门写一个转换函数,再把函数传进去即可
import json class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex def human2dict(oneman):
return {
'name': oneman.name,
'age': oneman.age,
'sex': oneman.sex
} oneman = Human('如花', 18, "女")
print(json.dumps(oneman, default=human2dict))
因为通常类的对象都有一个 __dict__ 属性,它就是一个 dict,用来存储实例变量。也有少数例外,比如定义了 __slots__ 的 类。同样的道理,如果我们要把 json 反序列化为一个 human 类的对象,json 模块的 loads 函数首先转换出一个 dict 对象,然后,我们传入的 object_hook 函数负责把 dict 转换为 human 类的对象。
import json class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex def human2dict(oneman):
return {
'name': oneman.name,
'age': oneman.age,
'sex': oneman.sex
} def dict2human(d):
return Human(d['name'], d['age'], d['sex']) oneman = Human('如花', 18, "女")
print(json.dumps(oneman, default=human2dict)) json_str = '{"name": "如花", "age": 18, "sex": "女"}'
print(json.loads(json_str, object_hook=dict2human))
我们仔细思考一下,自定义对象的属性是什么,其实自定义对象的属性最终还是由 Python 内置的数据类型表示的。我们对自定义对象进行序列化,本质是就是对对象的所有属性进行序列化,这些属性最终是由 Python 内置的数据类型表示的,我们只需要序列化这些数据就可以了,无论我们是把这些序列化后的数据存储在磁盘上 还是通过网络发送给其它机器,只需要存储或发送对象的所有属性即可
import json class Human(object):
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex oneman = Human('如花', 18, "女")
onemandata = {"name": oneman.name, "age": oneman.age, "sex": oneman.sex} seqdata = json.dumps(onemandata) # 序列化对象含有的属性
print(seqdata) reseqonemandata = json.loads(seqdata) # 反序列化
print(reseqonemandata)
时间转为json的两个解决方法
To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
``.default()`` method to serialize additional types), specify it with
the ``cls`` kwarg; otherwise ``JSONEncoder`` is used.cls代表类本身
``default(obj)`` is a function that should return a serializable version
of obj or raise TypeError. The default simply raises TypeError.
1、用类
def test(self):
js = {
'test5': datetime.datetime.now(),
}
print(js)
result = json.dumps(js, cls=CJsonEncoder)
print(result) class CJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(obj, datetime.date):
return obj.strftime('%Y-%m-%d')
else:
return json.JSONEncoder.default(self, obj)
2、用函数
def json_serial(obj):
if isinstance(obj,datetime.datetime):
serial=obj.isoformat()
return serial
elif isinstance(obj,datetime.date):
serial=obj.isoformat()
return serial
else:
return json.JSONEncoder.default(obj) js = {
'test5': datetime.datetime.now(),
}
print json.dumps(js, default=json_serial)
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式的更多相关文章
- Python笔记(十四)_永久存储pickle
pickle模块:将所有的Python对象转换成二进制文件存放 应用场景:编程时最好将大对象(列表.字典.集合等)用pickle写成永久数据包供程序调用,而不是直接写入程序 写入过程:将list转换为 ...
- Python第二十四天 binascii模块
Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...
- 初学 Python(十四)——生成器
初学 Python(十四)--生成器 初学 Python,主要整理一些学习到的知识点,这次是生成器. # -*- coding:utf-8 -*- ''''' 生成式的作用: 减少内存占有,不用一次性 ...
- 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘
孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...
- 孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式
孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 在我学习过的所有语言中,对VB系的语言比较喜欢,而对C系和J系 ...
- Python进阶(十四)----空间角度研究类,类与类之间的关系
Python进阶(十四)----空间角度研究类,类与类之间的关系 一丶从空间角度研究类 对象操作对象属性 class A(): address = '沙河' def __init__(self, na ...
- 学习python第十四天,模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码 ...
- python(31)——【sys模块】【json模块 & pickle模块】
一.sys模块 import sys sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit() #退出程序,正常退出时exit(0) sys.version #获取pyt ...
- python系列十四:Python3 文件
#!/usr/bin/python #Python3 文件 from urllib import requestimport pprint,pickle'''读和写文件open() 将会返回一个 fi ...
随机推荐
- MSSQL 更改表结构
更改表结构: alter TABLE 表1 ALTER COLUMN 列名1 NCHAR(40)
- 使用maven生成可执行jar包(包含依赖)
零零散散找了一些文章,有些感觉好乱,自己整理一下 以下是pom.xml里的配置,本来有很多依赖包,为了不让配置看着很长,我删了一些dependencies中我自己项目中引入的jar包 <proj ...
- springboot实现数据库中数据导出Excel功能
[转载]原文地址:https://blog.csdn.net/wilson_m/article/details/79021458 功能介绍 网上查找了一堆的数据导出代码,可能是自己基础比较薄弱的原因还 ...
- ansible基础-Jinja2模版 | 过滤器
Jinja2模版介绍 注:本文demo使用ansible2.7稳定版 在ansible基础-变量的「8.2 模版使用变量」章节中关于模版与变量也有所提及,有兴趣的同学可以去回顾一下. ansible通 ...
- Python开发:部分第三方库无法在线安装解决方法
前言:Python开发:Python2和Python3的共存和切换使用 一.问题如下: 1.截图: 2.错误信息: Could not find a version that satisfies th ...
- Android or Java的回调粗俗理解 这才是最通俗易懂的
FUCK,网上装逼者甚众矣! 网上一堆关于JAVA函数回调的见解文章,都说自己写的明白,但没几个我看的明白的. 不如自己写一个东西,回头自己看着舒服 回调函数:定义自己百度 干嘛的? 场景就是事务A执 ...
- python接口自动化(六)--发送get请求接口(详解)
简介 如果想用python做接口测试,我们首先有不得不了解和学习的模块.它就是第三方模块:Requests. 虽然Python内置的urllib模块,用于访问网络资源.但是,它用起来比较麻烦,而且,缺 ...
- mac 下常用命令备忘录
1.查看端口号 lsof -i: 2.杀死进程 kill 41321 3.查看文件夹文件 ls ls -l //看到文件及文件夹更多的内容 ls -a //隐藏的文件 ls -la //上面的组合 4 ...
- QPainterPath 不规则提示框(二)
前一篇讲过不规则提示框,但是提示框的方向是固定的,不能达到随意变换方向的效果,本接讲述可以动态变换方向的提示框 先看效果图 图1 图2 图3 图4 如上图1所示,上一篇文章的代码可以达到类似效果 本 ...
- 『集群』002 Slithice 集群配置工具 的使用
Slithice 集群配置工具 的使用 Slithice集群配置工具 主界面 在测试 Slithice 的 Demo 中,我配置了 7个服务端: 一个 WCF 的 中央服务端: 两个 WCF 的 成员 ...