python---shelve库快速入门

前言

shelve模块可以看做是pickle模块的升级版,因为shelve使用的就是pickle的序列化协议,但是shelve比pickle提供的操作方式更加简单、方便。shelve模块相对于其它两个模块在将Python数据持久化到本地磁盘时有一个很明显的优点就是,它允许我们可以像操作dict一样操作被序列化的数据,而不必一次性的保存或读取所有数据。

shelve序列化操作

这里我们的目的是测试将常用的数据类型保存到文件,包含:字典、元组、字符串、列表、数字、集合、time库的时间、自定义类的对象。shelve也可以保存绝大多数Python支持的数据类型,包括扩充的。

import shelve
import time


class test(object):
    def __init__(self,n):
        self.n = n

a = {'a':1,'b':2,'c':3}
b = (1,2,3)
c = '123'
d = [1,2,3]
e = 123
f = {1,2,3}
g = time.localtime()#当地时间
h = test('test')#自定义的类对象

save  = shelve.open('save')#无此文件就创建,有则打开
save['a'] = a#可以直接像字典一样保存
save['b'] = b
save['c'] = c
save['d'] = d
save['e'] = e
save['f'] = f
save['g'] = g
save['h'] = h
save.close()

由此可见,shelve保存内存数据是十分简单的,因为它使用了类似字典的形式保存。
生成的文件:
这里写图片描述
shelve反序列化操作

getinfo = shelve.open('save')
i = getinfo['a']
j = getinfo['b']
k = getinfo['c']
l = getinfo['d']
m = getinfo['e']
n = getinfo['f']
o = getinfo['g']
p = getinfo['h']
getinfo.close()

print(i)
print(j)
print(k)
print(l)
print(m)
print(n)
print(o)
print(p)

输出:

'a': 1, 'b': 2, 'c': 3}
(1, 2, 3)
123
[1, 2, 3]
123
{1, 2, 3}
time.struct_time(tm_year=2018, tm_mon=7, tm_mday=4, tm_hour=17, tm_min=51, tm_sec=48,
 tm_wday=2, tm_yday=185, tm_isdst=0)
<__main__.test object at 0x000001F3273DBF98>

可见,如果只是简单的序列化和反序列化,用shelve是非常容易实现的。其好处是可以用字典的方式很方便地从文件中取出数据

shelve其他操作

1. 查看序列化后的keys以及内容

getinfo = shelve.open('save')
for i in getinfo:#i是getinfo的keys循环变量
    print(i,'->',getinfo[i])

输出:

a -> {'a': 1, 'b': 2, 'c': 3}
b -> (1, 2, 3)
c -> 123
d -> [1, 2, 3]
e -> 123
f -> {1, 2, 3}
g -> time.struct_time(tm_year=2018, tm_mon=7, tm_mday=4, tm_hour=19, tm_min=22, tm_sec=57, 
tm_wday=2, tm_yday=185, tm_isdst=0)
h -> <__main__.test object at 0x000002634CE9BF28>

2. 删除元素、修改元素

getinfo.pop('d')#删除getinfo['d'] = [1,2,3]
getinfo['b'] = (1,2,3,4)#修改元素,如果‘b'不存在则扩充一个键值对
for i in getinfo:
    print(i)
for i in getinfo:
    print(i,'->',getinfo[i])

输出:

a -> {'a': 1, 'b': 2, 'c': 3}
b -> (1, 2, 3, 4)
c -> 123
e -> 123
f -> {1, 2, 3}
g -> time.struct_time(tm_year=2018, tm_mon=7, tm_mday=4, tm_hour=19, tm_min=34, tm_sec=32, 
tm_wday=2, tm_yday=185, tm_isdst=0)
h -> <__main__.test object at 0x000001F9688ECF28>

3. 批量序列化

new1 = 1
new2 = (1,2,3)
new3 = [4,5,6]
add_dict = {'1':new1,'2':new2,'3':new3}
getinfo.update(add_dict)
for i in getinfo:
    print(i, '->', getinfo[i])

输出:

a -> {'a': 1, 'b': 2, 'c': 3}
b -> (1, 2, 3)
c -> 123
e -> 123
f -> {1, 2, 3}
g -> time.struct_time(tm_year=2018, tm_mon=7, tm_mday=4, tm_hour=19, tm_min=45, tm_sec=12, 
tm_wday=2, tm_yday=185, tm_isdst=0)
h -> <__main__.test object at 0x0000023A09EBBF60>
1 -> 1
2 -> (1, 2, 3)
3 -> [4, 5, 6]
d -> [1, 2, 3]

输出的1,2,3就是新添加的。如果要批量序列化,这样的操作会很方便的

源代码声明

def open(filename, flag='c', protocol=None, writeback=False):
    """Open a persistent dictionary for reading and writing.

    The filename parameter is the base filename for the underlying
    database.  As a side-effect, an extension may be added to the
    filename and more than one file may be created.  The optional flag
    parameter has the same interpretation as the flag parameter of
    dbm.open(). The optional protocol parameter specifies the
    version of the pickle protocol (0, 1, or 2).

    See the module's __doc__ string for an overview of the interface.
    """

翻译

filename 参数是一个基础数据库的基本名。作为一个副作用,一个扩展可能会加入到filename里面,也就是创建的不止一个
文件。可选的flag参数和dbm.open()的flag参数有相同的解释。可选的protocol参数指明了pickle协议的版本(1,2或者3)
可以在该模块的__doc__字符串中看此接口的概述

# 参数flag的取值范围:
    #  'r':只读打开
    #  'w':读写访问
    #  'c':读写访问,如果不存在则创建
    #  'n':读写访问,总是创建新的、空的数据库文件
# protocol:与pickle库一致
    #   0: ascii串保存, 默认形式, 方便人读取
    #   1: 旧式兼容性较强2进制形式
    #   2: 支持新式类的2进制模式,Python2.3开始引入.
# writeback:为True时,当数据发生变化会回写,不过会导致内存开销比较大

猜你喜欢

转载自blog.csdn.net/tobe_numberone/article/details/80916475