shelve -- 用来持久化任意的Python对象

这几天接触了Python中的shelve这个module,感觉比pickle用起来更简单一些,它也是一个用来持久化Python对象的简单工具。当我们写程序的时候如果不想用关系数据库那么重量级的东东去存储数据,不妨可以试试用shelve。shelf也是用key来访问的,使用起来和字典类似。shelve其实用anydbm去创建DB并且管理持久化对象的。

创建一个新的shelf

直接使用shelve.open()就可以创建了

import shelve

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

try:

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

finally:

s.close()

如果想要再次访问这个shelf,只需要再次shelve.open()就可以了,然后我们可以像使用字典一样来使用这个shelf

import shelve

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

try:

existing = s['key1']

finally:

s.close()

print existing

当我们运行以上两个py,我们将得到如下输出:

$ python shelve_create.py

$ python shelve_existing.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

dbm这个模块有个限制,它不支持多个应用同一时间往同一个DB进行写操作。所以当我们知道我们的应用如果只进行读操作,我们可以让shelve通过只读方式打开DB:

import shelve

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

try:

existing = s['key1']

finally:

s.close()

print existing

当我们的程序试图去修改一个以只读方式打开的DB时,将会抛一个访问错误的异常。异常的具体类型取决于anydbm这个模块在创建DB时所选用的DB。

写回(Write-back)

由于shelve在默认情况下是不会记录待持久化对象的任何修改的,所以我们在shelve.open()时候需要修改默认参数,否则对象的修改不会保存。

import shelve

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

try:

print s['key1']

s['key1']['new_value'] = 'this was not here before'

finally:

s.close()

s = shelve.open('test_shelf.db', writeback=True)

try:

print s['key1']

finally:

s.close()

上面这个例子中,由于一开始我们使用了缺省参数shelve.open()了,因此第6行修改的值即使我们s.close()也不会被保存。

执行结果如下:

$ python shelve_create.py

$ python shelve_withoutwriteback.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

所以当我们试图让shelve去自动捕获对象的变化,我们应该在打开shelf的时候将writeback设置为True。当我们将writeback这个flag设置为True以后,shelf将会将所有从DB中读取的对象存放到一个内存缓存。当我们close()打开的shelf的时候,缓存中所有的对象会被重新写入DB。

import shelve

s = shelve.open('test_shelf.db', writeback=True)

try:

print s['key1']

s['key1']['new_value'] = 'this was not here before'

print s['key1']

finally:

s.close()

s = shelve.open('test_shelf.db', writeback=True)

try:

print s['key1']

finally:

s.close()

writeback方式有优点也有缺点。优点是减少了我们出错的概率,并且让对象的持久化对用户更加的透明了;但这种方式并不是所有的情况下都需要,首先,使用writeback以后,shelf在open()的时候会增加额外的内存消耗,并且当DB在close()的时候会将缓存中的每一个对象都写入到DB,这也会带来额外的等待时间。因为shelve没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入。

$ python shelve_create.py

$ python shelve_writeback.py

{'int': 10, 'float': 9.5, 'string': 'Sample data'}

{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}

{'int': 10, 'new_value': 'this was not here before', 'float': 9.5, 'string': 'Sample data'}

最后再来个复杂一点的例子:

#!/bin/env python

import time

import datetime

import md5

import shelve

LOGIN_TIME_OUT = 60

db = shelve.open('user_shelve.db', writeback=True)

def newuser():

global db

prompt = "login desired: "

while True:

name = raw_input(prompt)

if name in db:

prompt = "name taken, try another: "

continue

elif len(name) == 0:

prompt = "name should not be empty, try another: "

continue

else:

break

pwd = raw_input("password: ")

db[name] = {"password": md5_digest(pwd), "last_login_time": time.time()}

#print '-->', db

def olduser():

global db

name = raw_input("login: ")

pwd = raw_input("password: ")

try:

password = db.get(name).get('password')

except AttributeError, e:

print "\033[1;31;40mUsername '%s' doesn't existed\033[0m" % name

return

if md5_digest(pwd) == password:

login_time = time.time()

last_login_time = db.get(name).get('last_login_time')

if login_time - last_login_time < LOGIN_TIME_OUT:

print "\033[1;31;40mYou already logged in at: \033[0m" % datetime.datetime.fromtimestamp(last_login_time).isoformat()

db[name]['last_login_time'] = login_time

print "\033[1;32;40mwelcome back\033[0m", name

else:

print "\033[1;31;40mlogin incorrect\033[0m"

def md5_digest(plain_pass):

return md5.new(plain_pass).hexdigest()

def showmenu():

#print '>>>', db

global db

prompt = """

(N)ew User Login

(E)xisting User Login

(Q)uit

Enter choice: """

done = False

while not done:

chosen = False

while not chosen:

try:

choice = raw_input(prompt).strip()[0].lower()

except (EOFError, KeyboardInterrupt):

choice = "q"

print "\nYou picked: [%s]" % choice

if choice not in "neq":

print "invalid option, try again"

else:

chosen = True

if choice == "q": done = True

if choice == "n": newuser()

if choice == "e": olduser()

db.close()

if __name__ == "__main__":

showmenu()

感谢阅读本文,希望能帮助到大家,谢谢大家对本站的支持!

python中shelf对象_shelve 用来持久化任意的Python对象实例代码_python_脚本之家相关推荐

  1. python中shelf对象_shelve -- 用来持久化任意的Python对象

    这几天接触了Python中的shelve这个module,感觉比pickle用起来更简单一些,它也是一个用来持久化Python对象的简单工具.当我们写程序的时候如果不想用关系数据库那么重量级的东东去存 ...

  2. python中求合数_python输出100以内的质数与合数实例代码

    具体代码如下所述: __author__ = 'Yue Qingxuan' # -*- coding: utf-8 -*- #求质数 p=[2] for i in range(2,101): for ...

  3. python中的数据成员有两类_Python类和对象

    一.概念 1.面向对象(Object Oriented,即OO),是一种设计思想. 2.面向对象编程(Object Oriented Programming,即OOP),可以使软件设计更加灵活,并且能 ...

  4. python中可迭代对象是什么意思_python可迭代对象概念讲解

    python可迭代对象怎么理解 什么是可迭代对象? 简单的理解是可以用for循环的对象,就是可迭代对象.比如:list,字符串,dict,元组,生成器等. 具有可迭代的特征.(推荐学习:Python视 ...

  5. python中superclass是什么_深度解析并实现python中的super(转载,好文)

    大神半个月的成绩,让我看的叹为观止,建议看原帖地址,会让你对Python的描述符有更强的认识. 原文链接:https://blog.csdn.net/zhangjg_blog/article/deta ...

  6. python中ifelifelse用在什么结构_详解Python if-elif-else知识点

    有的时候,一个 if - else - 还不够用.比如,根据年龄的划分:条件1:18岁或以上:adult 条件2:6岁或以上:teenager 条件3:6岁以下:kid Python if-elif- ...

  7. python字符串能减吗_在python中减去两个字符串(Subtract two strings in python)

    在python中减去两个字符串(Subtract two strings in python) 我应该计算两个不同列表的元素之间的差异. 这是我的代码: import operator a = ['5 ...

  8. python中的常量可以修改吗_深入理解Python变量与常量

    变量是计算机内存中的一块区域,变量可以存储规定范围内的值,而且值可以改变.基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中.常量是一块只读的内存区域,常量一旦被初始化就不能被 ...

  9. python中for无限循环_关于循环:在Python中从1循环到无穷大

    在C语言中,我会这样做: 1 2 3 4int i; for (i = 0;; i++) if (thereIsAReasonToBreak(i)) break; 如何在Python中实现类似的功能? ...

最新文章

  1. 多线程的几种实现方法
  2. 航院 1874 畅通工程续
  3. 在线看大会!就来云栖号!
  4. oracle连接连表查询时,两表的连接字段类型不一致的时候,会导致ora 01722无效数字错误,这时候需要转换...
  5. 6.12使用tensorflow来搭建一个Transformer
  6. 《NX-OS与Cisco Nexus交换技术:下一代数据中心架构(第2版)》一2.9 本章小结...
  7. JDK8各个历史版本下载方法
  8. 几个在线网页聊天网站
  9. wjh2005:GitHub 上有哪些完整的 iOS-App 源码值得参考?
  10. 《少有人走的路-心智成熟的旅程》读书分享
  11. c语言cyc函数,cyc指标源码
  12. 一个小时学会Maven(参考资料)
  13. 2021年危险化学品经营单位安全管理人员考试内容及危险化学品经营单位安全管理人员考试资料
  14. 【English】二、It作为代词,可以代指什么
  15. Android开发中WIFI和GPRS网络的切换
  16. nacg python证书_这个nacg证书有用吗?
  17. 工作八年的程序员,却拿着毕业三年的工资,再不开窍就真晚了...
  18. 著名的海龟式期货交易系统完整版来了!值得收藏!
  19. 多智能体深度强化学习综述与批判——Matthew E. Taylor
  20. 2020.6.29 概率统计-Task04-方差分析

热门文章

  1. L1-049 天梯赛座位分配 (Python)
  2. PS自用(抠图、调色)
  3. 有备无患——数据中心基础设施备品备件管理
  4. 打造超级IP,你真悟错了道!
  5. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
  6. 服务器过载保护(上篇)——过载介绍
  7. MSDB数据库置疑状态的解决方法
  8. LeetCode——868. 二进制间距
  9. PHP Class各种方法和类的使用
  10. ORACLE通过dblink同步SDO_ORDINATE_ARRAY_STR的数据