gpt4 book ai didi

shelve 用来持久化任意的Python对象实例代码

转载 作者:qq735679552 更新时间:2022-09-27 22:32:09 33 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章shelve 用来持久化任意的Python对象实例代码由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

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

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

 创建一个新的shelf 。

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

?
1
2
3
4
5
6
7
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 。

?
1
2
3
4
5
6
7
8
9
import shelve
 
s = shelve. open ( 'test_shelf.db' )
try :
   existing = s[ 'key1' ]
finally :
   s.close()
 
print existing

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

?
1
2
3
4
5
$ python shelve_create.py
$ python shelve_existing.py
 
{ 'int' : 10 , 'float' : 9.5 , 'string' : 'Sample data' }

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

?
1
2
3
4
5
6
7
8
9
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()时候需要修改默认参数,否则对象的修改不会保存.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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()也不会被保存.

执行结果如下:

?
1
2
3
4
5
6
$ 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.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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没有办法知道缓存中哪些对象修改了,哪些对象没有修改,因此所有的对象都会被写入.

?
1
2
3
4
5
6
$ 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' }

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/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: <%s>\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()

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

原文链接:http://www.cnblogs.com/frankzs/p/5949645.html 。

最后此篇关于shelve 用来持久化任意的Python对象实例代码的文章就讲到这里了,如果你想了解更多关于shelve 用来持久化任意的Python对象实例代码的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com