7.2 shelve

pickle模块已经表现出它足够好的一面了。不过,由于数据的复杂性,pickle只能完成一部分工作,在另外更复杂的情况下,它就稍显麻烦了,于是,又有了shelve。

shelve模块也是标准库中的,先看看基本的写、读操作。

  1. >>> import shelve
  2. >>> s = shelve.open("22901.db")
  3. >>> s["name"] = "www.itdiffer.com"
  4. >>> s["lang"] = "python"
  5. >>> s["pages"] = 1000
  6. >>> s["contents"] = {"first":"base knowledge", "second":"day day up"}
  7. >>> s.close()

以上完成了数据写入的过程,其实,这很接近数据库的样式了。下面是读。

  1. >>> s = shelve.open("22901.db")
  2. >>> name = s["name"]
  3. >>> print name
  4. www.itdiffer.com
  5. >>> contents = s["contents"]
  6. >>> print contents
  7. {'second': 'day day up', 'first': 'base knowledge'}

看到输出的内容,你一定想到,肯定可以用for语句来读,想到了就用代码来测试,这就是Python交互模式的便利之处。

  1. >>> for k in s:
  2. ... print k, s[k]
  3. ...
  4. contents {'second': 'day day up', 'first': 'base knowledge'}
  5. lang python
  6. pages 1000
  7. name www.itdiffer.com

不管是写还是读,都似乎要简化了。所建立的对象s,就如同字典一样,可称之为类字典对象,所以,可以如同操作字典那样来操作它。

但是,小心有坑:

  1. >>> f = shelve.open("22901.db")
  2. >>> f["author"]
  3. ['qiwsir']
  4. >>> f["author"].append("Hetz") #试图增加一个
  5. >>> f["author"] #坑就在这里
  6. ['qiwsir']
  7. >>> f.close()

当试图修改一个已有键的值时没有报错,但是并没有修改成功。要填平这个坑,需要这样做:

  1. >>> f = shelve.open("22901.db", writeback=True) #多一个参数True
  2. >>> f["author"].append("Hetz")
  3. >>> f["author"] #没有坑了
  4. ['qiwsir', 'Hetz']
  5. >>> f.close()

还用for循环一下:

  1. >>> f = shelve.open("22901.db")
  2. >>> for k,v in f.items():
  3. ... print k,": ",v
  4. ...
  5. contents : {'second': 'day day up', 'first': 'base knowledge'}
  6. lang : python
  7. pages : 1000
  8. author : ['qiwsir', 'Hetz']
  9. name : www.itdiffer.com

shelve更像数据库了。不过,它还不是真正的数据库,真正的数据库在后面。