Shelve is used to persist arbitrary Python object instance code.

Source: Internet
Author: User

Shelve is used to persist arbitrary Python object instance code.

Shelve -- used to persist arbitrary Python objects

These days, I have come into contact with the shelve module in Python, which is easier to use than pickle. It is also a simple tool for persistence of Python objects. If you don't want to use a relational database to store data when writing a program, try shelve. Shelf is also accessed with a key, which is similar to a dictionary. Shelve uses anydbm to create databases and manage persistent objects.

 Create a new shelf

You can directly use shelve. open () to create

import shelves = shelve.open('test_shelf.db')try:  s['key1'] = { 'int': 10, 'float':9.5, 'string':'Sample data' }finally:  s.close()

If you want to access this shelf again, you only need to re-access the shelve. open (). Then we can use this shelf like using a dictionary.

import shelves = shelve.open('test_shelf.db')try:  existing = s['key1']finally:  s.close()print existing

When we run the above two py files, we will get the following output:

$ python shelve_create.py$ python shelve_existing.py{'int': 10, 'float': 9.5, 'string': 'Sample data'} 

The dbm module has a limitation. It does not support multiple applications to write data to the same database at the same time. So when we know that our application only performs read operations, we can let shelve open the database in read-only mode:

import shelves = shelve.open('test_shelf.db', flag='r')try:  existing = s['key1']finally:  s.close()print existing

When our program tries to modify a database opened in read-only mode, an access error will be thrown. The specific type of the exception depends on the DB used by the anydbm module when creating the database.

Write-back)

Because shelve does not record any modifications to the objects to be persisted by default, we need to modify the default parameters during shelve. open (). Otherwise, the changes to the objects will not be saved.

import shelves = 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()

In the above example, because the default parameter shelve. open () is used at the beginning, the modified value of row 6th will not be saved even if s. close () is used.

The execution result is as follows:

$ python shelve_create.py$ python shelve_withoutwriteback.py{'int': 10, 'float': 9.5, 'string': 'Sample data'}{'int': 10, 'float': 9.5, 'string': 'Sample data'} 

So when we try to allow shelve to automatically capture object changes, we should set writeback to True when we open shelf. When we set the flag of writeback to True, shelf will store all the objects read from the DB to a memory cache. When we close () to open the shelf, all objects in the cache will be re-written to the DB.

import shelves = 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()

The writeback method has advantages and disadvantages. The advantage is that it reduces the probability of errors and makes object persistence more transparent to users. However, this method is not required in all cases. First, after using writeback, shelf will increase memory consumption during open (), and when DB closes (), it will write every object in the cache to the DB, this will also lead to additional waiting time. Because shelve has no way to know which objects are modified in the cache and which objects are not modified, all objects will be written.

 $ 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'}

The following is a complex example:

#!/bin/env pythonimport timeimport datetimeimport md5import shelveLOGIN_TIME_OUT = 60db = 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 '-->', dbdef 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)uitEnter 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()

Thank you for reading this article and hope to help you. Thank you for your support for this site!

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.