python持久化缓存_python数据持久化

2ff34e647e2e3cdfd8dca593e17d9b0a.png

shelve– 用来持久化任意的python对象.使用比pickle简单一点, 是关系型数据库中的简单的替代品.

shelve是使用key值来进行访问的, 使用起来和字典类似, shelve实际上是使用anybm去创建的DB, 并且持久化管理对象.

创建一个新的shelve对象:1

2

3

4

5

6

7import shelve

s = shelve.open('test_shelf.db')

try:

s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }

finally:

s.close()

shelve对象的创建较为简单, 直接使用open方法打开一个数据库即可, 在数据库名字中添加上数据的地址和具体名称.

创建好的数据库使用和字典的方式较为相似, 后面的数据使用字典的存储方式.

如果需要再次访问这个数据, 只需要再次使用shelve.open()将文件打开即可

DBM后台模块不支持多个应用同一时间写入操作(有锁)如果一个文件只需要进行读取操作, 那么可以将文件的打开方式设置为只读模式1

2

3

4

5

6s = shelve.open('test.db', flag='r')

# 其中flag的取值主要有四种:

# flag = c, 代表可以读写一个新的或者是已经存在的数据库(存在就打开, 不存在就创建), 这是默认模式.

# flag = n, 当时用这种模式时候, 数据库总是创建一个新的数据库, 而不是去打开旧的数据库.

# flag = r, 当时用这种模式时候, 数据库是只读的.

# flag = w, 当时用这种模式时候, 只能打开已经存在的数据库, 如果数据库不存在就会报错.

shelve对象的写回操作shelve在默认情况下不会记录持久化对象的任何修改, 所以在使用shelve.open()时候, 如果不添加writeback=True, 那么在更改shelve中数据的时候, 更改的数据不会被保存. 这里的数据表变化的含义是已经有的存储对象中值发生了变化, 而不是说新创建一个键值对.

当吧writeback设置为true后, shelf将会将所有的从DB中读取的对象存放在一个内存缓存中, 当我们close一个shelve时候, 缓存中的所有的对象都会被重新写入DB当中.

writeback方式有优点也有缺点.优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了.

但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消, 并且当DB在close()的时候会将缓存中的每一个对象都写入到DB, 这也会带来额外的等待时间. (因为shelve没有办法知道缓存中哪些对象修改了, 哪些对象没有修改, 因此所有的对象都会被写入.)

shelve对象的删除操作:1

2del shelve["key"]

# 这种方式可以直接删除一条记录.shelve可以理解为一个字典, 通过shelve.keys()可以直接拿到shelve中所有的键值对.

通过 下面这种方式可以遍历一个shelve中所有的数据.1

2for item in sh.items():

print('键[{}] = 值[{}]'.format(item[0], sh[item[0]]))

pickle模块. Python最基本的数据持久化存储工具.pickle 简单理解就是一个复杂的shelve.

pickle.dump(obj, file, protocol=None,)必填参数obj表示将要封装的对象

必填参数file表示obj要写入的文件对象,file必须以二进制可写模式打开,即“wb”

可选参数protocol表示告知pickler使用的协议,支持的协议有0,1,2,3,默认的协议是添加在Python 3中的协议3.

pickle.load(file,*,fix_imports=True, encoding=”ASCII”, errors=”strict”)必填参数file必须以二进制可读模式打开,即“rb”,其他都为可选参数.

pickle.dumps(obj):以字节对象形式返回封装的对象,不需要写入文件中.

pickle.loads(bytes_object): 从字节对象中读取被封装的对象,并返回.1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23# dumps功能

import pickle

data = ['aa', 'bb', 'cc']

# dumps 将数据通过特殊的形式转换为只有python语言认识的字符串

p_str = pickle.dumps(data)

print(p_str)

>>>b'x80x03]qx00(Xx02x00x00x00aaqx01Xx02x00x00x00bbqx02Xx02x00x00x00ccqx03e.

# loads功能

# loads 将pickle数据转换为python的数据结构

mes = pickle.loads(p_str)

print(mes)

>>>['aa', 'bb', 'cc']

# dump功能

# dump 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件

with open('D:/tmp.pk', 'w') as f:

pickle.dump(data, f)

# load功能

# load 从数据文件中读取数据,并转换为python的数据结构

with open('D:/tmp.pk', 'r') as f:

data = pickle.load(f)

h5py模块使用(这个模块比较适合科学计算, 即和numpy进行搭配使用):一个HDF5文件是一种存放两类对象的容器:dataset和group.

Dataset是类似于数组的数据集,而group是类似文件夹一样的容器,存放dataset和其他group。在使用h5py的时候需要牢记一句话:groups类比词典,dataset类比Numpy中的数组.

文件的打开:1

2import h5py

f = h5py.File("file name", "r")由于h5py文件类似于python中的字典对象, 所以可以使用f.keys()直接访问文件中的所有的键值对.1

2f.keys()

>>> [u'mydataset']

从h5文件中拿到的数据是一个dataset对象, 我们可以像访问Numpy的数组一样访问他的属性和数据.

创建一个h5文件:使用w模式打开一个文件:1

2

3

4

5

6

7

8import h5py

import numpy as np

f = h5py.File("mytestfile.hdf5", "w")

dset = f.create_dataset("mydataset", (100,), dtype='i')

# 或者也可以使用Numpy数组来初始化一个dataset

arr = np.arange(100)

dset = f.create_dataset("init", data=arr)

在缺省设置下, HDF5数据集在内存中是连续布局的, 也就是按照传统的C序.

Dataset也可以在HDF5的分块存储布局下创建, 也就是dataset被分为大小相同的若干块随意地分布在磁盘上, 并使用B树建立索引.

HDF5文件的分层结构:“HDF”代表”Hierarchical Data Format”(分层数据格式).

HDF5文件中group对象类似于文件夹,我们创建的文件对象本身就是一个group,称为root group.1

2f.name

>>> u'/'

创建subgroup是使用create_group的方法实现的, 在创建之前, 需要将文件使用读写模式打开.1

2>>> f = h5py.File('mydataset.hdf5', 'r+')

>>> grp = f.create_group("subgroup")

为了遍历一个group内的所有直接和间接成员,我们可以使用group的visit()和visititerms()方法,这些方法需要接收一个回调函数作为参数。1

2

3

4

5

6

7

8def printname(name):

print name

f.visit(printname)

>>>mydataset

>>>subgroup

>>>subgroup/another_dataset

>>>subgroup2

>>>subgroup2/dataset_threeHDF5的一个很棒的特点是你可以在数据旁边存储元数据。所有的group和dataset都支持叫做属性的数据形式。属性通过attrs成员访问,类似于python中词典格式。

你可能感兴趣的:(python持久化缓存)