目录

Python简单又好友的数据存储方案-Shelve学习笔记

一、前言

  • 开发工程中不可避免地会涉及到数据的存储、读取。
  • 存储数据的方式有很多,如:数据库存储、文件存储等。
  • Python 提供了一种较轻量级简单的存储方法-Shelve,shelve的操作是非常简单的。

二、Shelve介绍

  • Python中的Shelve模块提供了一些简单的数据操作,与Pytho的dbm类似,但是两者又是有区别的。
  • 区别如下: 1、相同点:两者都是以key-value的形式保存数据,就像字典一样。 2、不同点:shelve中,key必须是字符串类型,value可以是python支持的所有数据类型。dbm中key、value都必须为字符串(似乎看到了shelve的一些优越的地方了)

三、Shelve的使用

  • Ok,接下来我们通过一些小的demo来介绍shelve的使用

      import shelve
    
      s = shelve.open('test.db');
      s['x']= [1,2,3,4];
      print(s['x'])
    
  • 执行完后你会发现我们的目录下面多了一个test.db文件。

用shelve时容易踩的坑

  • 看如下代码,我们赋值之后想追加点数据,所以就这样做了:

      import shelve
    
      s = shelve.open('test.db');
      s['x']= [1,2,3,4];
      s['x'].append(5);
      print(s['x'])
    
  • 但是结果是这样的— [1, 2, 3, 4]

  • 产生这个现象的原因是这样的:1、当我们执行s[‘x’]= [1,2,3,4];的时候,shelve将数据以key为‘x’的形式保存了,已存在则覆盖。2、当我们执行s[‘x’].append(5);时,此时的s[‘x’]是数据库的一个副本,我们只是将5添加到了s[‘x’]的副本中,但是副本并没有被保存到数据库中。3、当我们执行print(s[‘x’])时,其再次从数据库中读取了s[‘x’]对应的内容,所以数据中并不存在后面添加的5.

解决方案

  • 1、解决方案1:

  • ok,既然是当直接赋值的时候会触发存储操作,那么我们可以这样子

      import shelve
    
      s = shelve.open('test.db');
      s['x']= [1,2,3,4];
      t= s['x'];
      t.append(5);
      s['x'] = t;
      print(s['x'])
    
  • 输出结果为:[1, 2, 3, 4, 5]

  • 2、解决方案2:在Python2.4之后,open函数提供了writeback参数,表示是否存入缓存中,默认是false。我们只需在调用open函数时设置为Ture即可。但是要注意,在结束前一点要调用close函数,将缓存中的数据存储硬盘中,如果不调用的话,那么,你本次存储的数据就会因为内存的回收而丢失了。

  • 修改代码如下

      s = shelve.open('test.db',writeback=True);
      s['x']= [1,2,3,4];
    
      s['x'].append(5);
      s.close()
    
      s = shelve.open('test.db',writeback=True);
      print(s['x'])
    
  • 输出结果为:[1, 2, 3, 4, 5]

验证不执行close的危害

  • 我们可以测试不执行close时,数据是否真的丢失
  • 当注释调s.close()之后再运行,你会发现报错了。
  • 所以,一定要记得调用close方法哦。

最保险的close调用方式

  • 我们可以使用try finally来实现。

      import shelve
    
      s = shelve.open('test.db',writeback=True);
      try:
      	s['x']= [1,2,3,4];
      	s['x'].append(5);
      except Exception as e:
      	print('Exception msg is %s :'% e);
      finally:
      	s.close();
    
      s = shelve.open('test.db',writeback=True);
      print(s['x'])