Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式

时间:2022-09-02 08:29:09

Python第十四天 序列化  pickle模块  cPickle模块  JSON模块  API的两种格式

目录

Pycharm使用技巧(转载)

Python第一天  安装  shell  文件

Python第二天  变量  运算符与表达式  input()与raw_input()区别  字符编码  python转义符  字符串格式化

Python第三天 序列  5种数据类型  数值  字符串  列表  元组  字典

Python第四天   流程控制   if else条件判断   for循环 while循环

Python第五天   文件访问    for循环访问文件    while循环访问文件   字符串的startswith函数和split函数

Python第六天   类型转换

Python第七天   函数  函数参数   函数变量   函数返回值  多类型传值    冗余参数   函数递归调用   匿名函数   内置函数   列表表达式/列表重写

Python第八天  模块   包   全局变量和内置变量__name__    Python path

Python第九天  面向对象  类定义   类的属性    类的方法    内部类   垃圾回收机制   类的继承 装饰器

Python第十天   print >> f,和fd.write()的区别    stdout的buffer  标准输入 标准输出  标准错误   重定向 输出流和输入流

Python第十一天    异常处理  glob模块和shlex模块    打开外部程序和subprocess模块  subprocess类  Pipe管道  operator模块   sorted函数   生成器  walk模块   hashlib模块

Python第十二天     收集主机信息     正则表达式  无名分组   有名分组

Python第十三天   django 1.6   导入模板   定义数据模型   访问数据库   GET和POST方法    SimpleCMDB项目   urllib模块   urllib2模块  httplib模块  django和web服务器整合  wsgi模块   gunicorn模块

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 数据类型

Python第十四天 序列化  pickle模块  cPickle模块  JSON模块  API的两种格式

我们自定义的类对象是否可以用 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的两种格式的更多相关文章

  1. Python笔记&lpar;十四&rpar;&lowbar;永久存储pickle

    pickle模块:将所有的Python对象转换成二进制文件存放 应用场景:编程时最好将大对象(列表.字典.集合等)用pickle写成永久数据包供程序调用,而不是直接写入程序 写入过程:将list转换为 ...

  2. Python第二十四天 binascii模块

    Python第二十四天 binascii模块 binascii用来进行进制和字符串之间的转换 import binascii s = 'abcde' h = binascii.b2a_hex(s) # ...

  3. 初学 Python(十四)——生成器

    初学 Python(十四)--生成器 初学 Python,主要整理一些学习到的知识点,这次是生成器. # -*- coding:utf-8 -*- ''''' 生成式的作用: 减少内存占有,不用一次性 ...

  4. 孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘

    孤荷凌寒自学python第二十四天python类中隐藏的私有方法探秘 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天发现了python的类中隐藏着一些特殊的私有方法. 这些私有方法不管我 ...

  5. 孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式

    孤荷凌寒自学python第十四天python代码的书写规范与条件语句及判断条件式 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 在我学习过的所有语言中,对VB系的语言比较喜欢,而对C系和J系 ...

  6. Python进阶&lpar;十四&rpar;----空间角度研究类&comma;类与类之间的关系

    Python进阶(十四)----空间角度研究类,类与类之间的关系 一丶从空间角度研究类 对象操作对象属性 class A(): address = '沙河' def __init__(self, na ...

  7. 学习python第十四天,模块

    Python 模块(Module),是一个 Python 文件,以 .py 结尾,包含了 Python 对象定义和Python语句. 模块让你能够有逻辑地组织你的 Python 代码段. 把相关的代码 ...

  8. python(31)——【sys模块】【json模块 &amp&semi; pickle模块】

    一.sys模块 import sys sys.argv #命令行参数List,第一个元素是程序本身路径 sys.exit() #退出程序,正常退出时exit(0) sys.version #获取pyt ...

  9. python系列十四:Python3 文件

    #!/usr/bin/python #Python3 文件 from urllib import requestimport pprint,pickle'''读和写文件open() 将会返回一个 fi ...

随机推荐

  1. qemu源码架构

    前言:本文主要概括了QEMU的代码结构,特别从代码翻译的角度分析了QEMU是如何将客户机代码翻译成TCG代码和主机代码并且最终执行的过程.并且在最后描述了QEMU和KVM之间联系的纽带. 申明:本文前 ...

  2. 一个关于正整数x的约数个数的结论

    分析理解:x的每一个约数都是由x的若干个质因数的积构成. 再根据乘法原理,每个质因数Pi的选择可以是0~Ni个,所以上述结论成立.

  3. 02&lowbar;HTML5&plus;CSS3详解第五、六天(实战篇之HTML5制作企业网站)

    [废话连篇 - 实战篇,没什么好说的,最后一章兼容性问题懒得看了,over] Details 一.Xmind部分 xmind教程:http://www.jianshu.com/p/7c488d5e4b ...

  4. &lbrack;SDOI2012&rsqb;Longge的问题

    题目大意: 网址:https://www.luogu.org/problemnew/show/P2303 大意:给定一个N,求\(\Sigma_{i=1}^N gcd(i, N);\). 题目解法: ...

  5. python 进程池Pool的apply&lowbar;async方法以及一些需要注意的地方

    在写多进程的时候我发现一个问题,用Pool的apply_async(异步非阻塞)的时候传入实例函数会出错,或者说是子进程被跳过似的感觉(python2.7). 但是用python3.7的话没有任何问题 ...

  6. 自定义simple&lowbar;tag和filter在html中渲染出来的联系和区别

    关于 simple_tag: 1,在app下创建一个(templatetags)目录,(被引用的模块必须放在该目录下,且目录名称不可更改): 2,创建任意py文件: 3,创建template对象: f ...

  7. Rosserial实现Windows-ROS交互操作

    安装 sudo apt-get install ros-indigo-rosserial-windows sudo apt-get install ros-indigo-rosserial-serve ...

  8. El表达式对照表

    设置  session.getAttribute("date" "date") 取得username的值   (String)session.getValue( ...

  9. 李嘉诚 《Are you ready》

    当你们梦想着为伟大成功的时候,你有没有刻苦的准备? 当你们有野心作领袖的时候,你有没有服务于人的谦恭? 我们常常都想有所获得,但我们有没有付出的情操? 我们都希望别人听到自己的话,我们有没有耐性聆听别 ...

  10. &lbrack;BZOJ5250&rsqb;&lbrack;九省联考2018&rsqb;秘密袭击&lpar;DP&rpar;

    5250: [2018多省省队联测]秘密袭击 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 3  Solved: 0[Submit][Status][D ...