Python模块--json&pickle&shelve

一 eval了解

之前使用过eval内置方法可以将一个字符串转成python对象(字典、列表等),但是eval方法存在局限性的,对于普通的数据类型eval没有问题,但遇到特殊类型的时候eval存在问题。

eval()官方文档里面给出来的功能解释是:将字符串string对象转化为有效的表达式参与求值运算返回计算结果,以下是eval的语法:

eval(expression[, globals[, locals]])
	参数说明:
	expression -- 表达式
	globals -- 变量作用域,全局命名空间,如果被提供,则必须是一个字典对象
	locals -- 变量作用域,局部命名空间,如果被提供,可以是任何映射对象

简单示例如下:

print(eval("1+3+5*23"))     # 119
print(eval('pow(2,5)'))     # 32

x=20
print(eval('x'))            # 20
print(eval('20*x'))         # 400

l = "['joe1991',18,[1,2,3]]"
d = "{'name':'joe1991','age':18,'email':'xxxx'}"
print(type(l), type(eval(l)))           # <class 'str'> <class 'list'>
print(type(d), type(eval(d)))           # <class 'str'> <class 'dict'>

二 什么是序列化

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

序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

常用模块有json,pickle

三 json

json用于字符串和 python数据类型间进行转换,提供了四个功能:dumps、dump、loads、load。JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:

image

示例如下:

import json

dic = {'name': 'joe1991', 'age':18,'email':'xxxx'}
print(type(dic))     # <class 'dict'>

# 序列化
data = json.dumps(dic)
print(type(data))       # <class 'str'>

# 反序列化
# data = json.loads(data)
# print(type(data))       # <class 'dict'>

# 序列化后写入文件
f = open('序列化对象', 'w')
f.write(data)  # 等价于json.dump(dic,f)
f.close()

# 反序列化
f = open('序列化对象')
data = json.loads(f.read())  # 等价于data=json.load(f)
print(data)     # {'name': 'joe1991', 'email': 'xxxx', 'age': 18}

注意点:

  • json不认单引号
  • 无论数据是怎样创建的,只要满足json格式,就可以json.loads,不一定非要dumps的数据才能loads
# dic = "{'1':111}"       # json不认单引号
# dic = str({"1":111})    # 报错,因为生成的数据还是单引号:{'1': 111}

dic = '{"1":"111"}'
print(json.loads(dic))

四 pickle

pickle用于python特有的类型 和 python的数据类型间进行转换,也提供了四个功能:dumps、dump、loads、load。示例代码如下:

import pickle

dic = {'name': 'joe1991', 'age':18,'email':'xxxx'}
print(type(dic))     # <class 'dict'>

# 序列化
data = pickle.dumps(dic)
print(type(data))       # <class 'bytes'>

# 反序列化
# data = pickle.loads(data)
# print(type(data))     # <class 'dict'>

# 序列化后写入文件
f = open('序列化对象', 'wb')    # 注意是w是写入str,wb是写入bytes,data是'bytes'
f.write(data)                  # 等价于pickle.dump(dic,f)
f.close()

# 反序列化
f = open('序列化对象','rb')
data = pickle.loads(f.read())  # 等价于data=pickle.load(f)
print(data)                    # {'name': 'joe1991', 'email': 'xxxx', 'age': 18}

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

五 json vs  pickle

json

优点:跨语言,体积小

缺点:只能支持int/str/list/tuple/dict

pickle

优点:转为Python设计,支持Python所有的数据类型

缺点:只能在Python中使用,存储数据占空间大

六  shelve

shelve模块比pickle模块简单,只有一个open函数,它是一个通过k,v方式将内存数据通过文件持久化的模块。key必须为字符串,而值可以是python所支持的数据类型。实例如下:

# 序列化
import shelve
 
 
f = shelve.open('shelve_test')  # 打开一个文件
names = ['Joe','Tom','Jack']
info = {'name':'Joe','age':22}
f['names'] = names  # 持久化
f['info'] = info  # 持久化
f.close()
 
# 反序列化
import shelve
 
 
f = shelve.open('shelve_test')  # 打开一个文件
print(f['names'])  # 不存在则报错
print(f['info'])
del f['names']  # 可以删除
f.close()
posted @ 2018-06-28 11:13  Joe1991  阅读(159)  评论(0)    收藏  举报