python 模块 - 序列化 json 和 pickle

1,引入

之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值。

import json
x = "[nuaa,true,dalse,1]"

# print(eval(x)) # 报错,无法解析null类型,而json就可以

print(json.dumps(x)) # "[nuaa,true,dalse,1]"

2,什么时序列化?

我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。

3,为什么要序列化?

1:持久保存状态

需知一个软件/程序的执行就在处理一系列状态的变化,在编程语言中,‘状态‘会以各种各样有结构的数据类型(也可简单的理解为变量)的形式被保存在内存中。

内存是无法永久保存数据的,当程序运行了一段时间,我们断电或者重启程序,内存中关于这个程序的之前一段时间的数据(有结构)都被清空了。

在断电或重启程序之前将程序当前内存中所有的数据都保存下来(保存到文件中),以便于下次程序执行能够从文件中载入之前的数据,然后继续执行,这就是序列化。

具体的来说,你玩使命召唤闯到了第13关,你保存游戏状态,关机走人,下次再玩,还能从上次的位置开始继续闯关。或如,虚拟机状态的挂起等。

2:跨平台数据交互

序列化之后,不仅可以把序列化后的内容写入磁盘,还可以通过网络传输到别的机器上,如果收发的双方约定好实用一种序列化的格式,那么便打破了平台/语言差异化带来的限制,实现了跨平台数据交互。

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

4,如何和序列化之 json 和 pickle:

  json

一,python类型数据和json数据格式互相转换

pthon 中str类型到json中转为unicode类型,None转为null,dict对应object

二,数据encoding和decoding

所谓简单类型就是指上表中出现的python类型。

dumps:  将对象序列化

import json

# 简单编码===========================================
print json.dumps([‘foo‘, {‘bar‘: (‘baz‘, None, 1.0, 2)}])
# ["foo", {"bar": ["baz", null, 1.0, 2]}]

#字典排序
print json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True)
# {"a": 0, "b": 0, "c": 0}

#自定义分隔符
print json.dumps([1,2,3,{‘4‘: 5, ‘6‘: 7}], sort_keys=True, separators=(‘,‘,‘:‘))
# [1,2,3,{"4":5,"6":7}]
print json.dumps([1,2,3,{‘4‘: 5, ‘6‘: 7}], sort_keys=True, separators=(‘/‘,‘-‘))
# [1/2/3/{"4"-5/"6"-7}]

#增加缩进,增强可读性,但缩进空格会使数据变大
print json.dumps({‘4‘: 5, ‘6‘: 7}, sort_keys=True,indent=2, separators=(‘,‘, ‘: ‘))
# {
#   "4": 5,
#   "6": 7
# }

# 另一个比较有用的dumps参数是skipkeys,默认为False。
# dumps方法存储dict对象时,key必须是str类型,如果出现了其他类型的话,那么会产生TypeError异常,如果开启该参数,设为True的话,会忽略这个key。
data = {‘a‘:1,(1,2):123}
print json.dumps(data,skipkeys=True)
#{"a": 1}

python2代码

dump:  将对象序列化并保存到文件

#将对象序列化并保存到文件
obj = [‘foo‘, {‘bar‘: (‘baz‘, None, 1.0, 2)}]
with open(r"c:\json.txt","w+") as f:
    json.dump(obj,f)

loads:  将序列化字符串反序列化

import json

obj = [‘foo‘, {‘bar‘: (‘baz‘, None, 1.0, 2)}]
a= json.dumps(obj)
print(json.loads(a))
# [u‘foo‘, {u‘bar‘: [u‘baz‘, None, 1.0, 2]}]

 load:  将序列化字符串从文件读取并反序列化

with open(r"c:\json.txt","r") as f:
    print (json.load(f))

三、自定义复杂数据类型编解码

例如我们碰到对象datetime,或者自定义的类对象等json默认不支持的数据类型时,我们就需要自定义编解码函数。有两种方法来实现自定义编解码。

1、方法一:自定义编解码函数

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import datetime,json

dt = datetime.datetime.now()

def time2str(obj):
    #python to json
    if isinstance(obj, datetime.datetime):
        json_str = {"datetime":obj.strftime("%Y-%m-%d %X")}
        return json_str
    return obj

def str2time(json_obj):
    #json to python
    if "datetime" in json_obj:
        date_str,time_str = json_obj["datetime"].split(‘ ‘)
        date = [int(x) for x in date_str.split(‘-‘)]
        time = [int(x) for x in time_str.split(‘:‘)]
        dt = datetime.datetime(date[0],date[1], date[2], time[0],time[1], time[2])
        return dt
    return json_obj

a = json.dumps(dt,default=time2str)
print a
# {"datetime": "2016-10-27 17:38:31"}
print json.loads(a,object_hook=str2time)
# 2016-10-27 17:38:31

python2代码

2、方法二:继承JSONEncoder和JSONDecoder类,重写相关方法

#! /usr/bin/env python
# -*- coding:utf-8 -*-
# __author__ = "TKQ"
import datetime,json

dt = datetime.datetime.now()
dd = [dt,[1,2,3]]

class MyEncoder(json.JSONEncoder):
    def default(self,obj):
        #python to json
        if isinstance(obj, datetime.datetime):
            json_str = {"datetime":obj.strftime("%Y-%m-%d %X")}
            return json_str
        return obj

class MyDecoder(json.JSONDecoder):
    def __init__(self):
        json.JSONDecoder.__init__(self, object_hook=self.str2time)

    def str2time(self,json_obj):
        #json to python
        if "datetime" in json_obj:
            date_str,time_str = json_obj["datetime"].split(‘ ‘)
            date = [int(x) for x in date_str.split(‘-‘)]
            time = [int(x) for x in time_str.split(‘:‘)]
            dt = datetime.datetime(date[0],date[1], date[2], time[0],time[1], time[2])
            return dt
        return json_obj

# a = json.dumps(dt,default=time2str)
a =MyEncoder().encode(dd)
print a
# [{"datetime": "2016-10-27 18:14:54"}, [1, 2, 3]]
print MyDecoder().decode(a)
# [datetime.datetime(2016, 10, 27, 18, 14, 54), [1, 2, 3]]

python2代码

===========================================================

  pickle

python的pickle模块实现了python的所有数据序列和反序列化。基本上功能使用和JSON模块没有太大区别,方法也同样是dumps/dump和loads/load。cPickle是pickle模块的C语言编译版本相对速度更快。

与JSON不同的是pickle不是用于多种语言间的数据传输,它仅作为python对象的持久化或者python程序间进行互相传输对象的方法,因此它支持了python所有的数据类型。

pickle反序列化后的对象与原对象是等值的副本对象,类似与deepcopy。

dumps/dump序列化

from datetime import date

try:
    import cPickle as pickle    #python 2
except ImportError as e:
    import pickle   #python 3

src_dic = {"date":date.today(),"oth":([1,"a"],None,True,False),}
det_str = pickle.dumps(src_dic)
print det_str
# (dp1
# S‘date‘
# p2
# cdatetime
# date
# p3
# (S‘\x07\xe0\n\x1b‘
# tRp4
# sS‘oth‘
# p5
# ((lp6
# I1
# aS‘a‘
# aNI01
# I00
# tp7
# s.
with open(r"c:\pickle.txt","w") as f:
    pickle.dump(src_dic,f)

loads/load反序列化

from datetime import date

try:
    import cPickle as pickle    #python 2
except ImportError as e:
    import pickle   #python 3

src_dic = {"date":date.today(),"oth":([1,"a"],None,True,False),}
det_str = pickle.dumps(src_dic)
with open(r"c:\pickle.txt","r") as f:
    print (pickle.load(f))
# {‘date‘: datetime.date(2016, 10, 27), ‘oth‘: ([1, ‘a‘], None, True, False)}

JSON和pickle模块的区别

1、JSON只能处理基本数据类型。pickle能处理所有Python的数据类型。

2、JSON用于各种语言之间的字符转换。pickle用于Python程序对象的持久化或者Python程序间对象网络传输,但不同版本的Python序列化可能还有差异。

原文地址:https://www.cnblogs.com/peng104/p/9582004.html

时间: 2024-10-29 19:06:28

python 模块 - 序列化 json 和 pickle的相关文章

python模块(json和pickle模块)

json和pickle模块,两个都是用于序列化的模块 • json模块,用于字符串与python数据类型之间的转换 • pickle模块,用于python特有类型与python数据类型之间的转换 两个模块,都提供了dumps,dump,loads,load 4个功能 1 import json 2 s = '{"key1":"value1","key2":"value2"}' # ==> 用json模块将字符串转化成其他

常用模块一(os模块、序列化模块(json,pickle))

一.os模块 os模块是与操作系统交互的一个接口. import os # 和文件和文件夹的操作有关 os.makedirs('dirname1/dirname2') # 可生成多层递归目录 os.removedirs('dirname1') # 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') # 生成单级目录:相当于shell中mkdir dirname os.rmdir('dirname') # 删除单级空目录,若目录不为空则无法

模块 序列化 json pickle shelv xml

序列化 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes. json 模块 json.dump(d,f) json.load(f) #与文件得交互 dump(可多次,但不那样做) load(只可一次) 把数据类型转成字符串存到内存里得意义? json.dumps(data) json.loads(q) #与内存得交互 1.把内存数据 通过网络 共享给远程其他人 必须:bytes 2.定义了不同语言之间得交互规则 2.1 纯文

内置模块(一)——序列化模块:json、pickle、shelve

一.序列化模块 1.什么是序列化呢? 序列化的本质就是:将一种数据结构(如字典.列表)等转换成一个特殊的序列(字符串或者bytes)的过程就叫做序列化. 特别注意:特殊的序列,而不是我们常用的str这种字符串. 2.序列化的作用 如果你写入文件中的字符串是一个序列化后的特殊的字符串,那么当你从文件中读取出来,是可以转化回原数据结构的. 3.小小总结: 序列化模块就是:将一个常见的数据结构转化成一个特殊的序列,并且这个特殊的序列还可以反解回去.它的主要用途:文件读写数据,网络传输数据. 二.pyt

Python 序列化Json、Pickle

#!/usr/bin/env python # -*- coding:utf-8 -*- # author: Changhua Gong ''' Json仅支持简单的数据类型,不支持复杂类型的序列化,如函数 ''' import json info = {"name":"daidai", "salary":15000} # 序列化 with open("test.txt", "w") as f: # f.w

Python之路-json和pickle序列化/反序列化

首先引入json模块 序列化:使用json的dumps方法 反序列化:使用json的loads方法 过程:在json序列化后就可以将序列化的数据类型写入文件,然后在从文件中读出该数据类型,然后在进行反序列化 json对象中的其他的方法:dump(info,f)>>>其中Info是需要序列化的数据,f是一个文件句柄:load(f)>>>使用这两个方法不要在对文件进行读写 pickle和json使用方法类似,只是名字不同且pickle可以处理复杂数据类型而json不能(pi

Python常用模块之json、pickle、random、hashlib、collections

1.json和pickle json用于字符串和Python数据类型间进行转换pickle用于python特有的类型和python的数据类型间进行转换json和pickle均提供了四种方法dumps,dump,loads,load ##json dumps() ##转换成字符串 loads() ##将json编码的字符串再转换为python的数据结构 dump() ##转换成字符串并存存储到文件中 load() ##从数据文件中读取数据,并将json编码的字符串转换为python的数据结构 >>

shutil模块、json和pickle模块

shutil模块: 高级的文件.文件夹.压缩包处理模块 json和pickle模块 之前学过eval内置方法可以将一个字符串转化成Python对象,但eval方法是有局限性的,对于普通的数据类型,json.loads.eval都可以使用,但遇到特殊类型的时候,eval就不能使用了, 所以eval的重点通常还是用来执行一个字符串表达式,并返回表达式的值. 序列化:我们把对象从内存中变成可存蓄或可传送的过程称为序列化,在Python中叫picking,在其他语言中叫serialization .ma

python 模块之-json

python 模块json import json x="[null,true,false,1]" print(json.loads(x)) #----------------------------序列化 import json dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=json.dumps(dic) print(type(j))#<class 'str'