"shelve" — Python オブジェクトの永続化
**************************************

**ソースコード:** Lib/shelve.py

======================================================================

「シェルフ (shelf, 棚)」 は辞書に似た永続性を持つオブジェクトです。 「
dbm」 データベースとの違いは、シェルフの値 (キーではありません！) は実
質上どんな Python オブジェクトにも — "pickle" モジュールが扱えるなら何
でも — できるということです。これにはほとんどのクラスインスタンス、再
帰的なデータ型、沢山の共有されたサブオブジェクトを含むオブジェクトが含
まれます。キーは通常の文字列です。

shelve.open(filename, flag='c', protocol=None, writeback=False)

   Open a persistent dictionary.  The filename specified is the base
   filename for the underlying database.  As a side-effect, an
   extension may be added to the filename and more than one file may
   be created.  By default, the underlying database file is opened for
   reading and writing.  The optional *flag* parameter has the same
   interpretation as the *flag* parameter of "anydbm.open()".

   By default, version 0 pickles are used to serialize values.  The
   version of the pickle protocol can be specified with the *protocol*
   parameter.

   バージョン 2.3 で変更: The *protocol* parameter was added.

   Python の意味論により、シェルフには永続的な辞書の可変エントリがいつ
   変更されたかを知る術がありません。 デフォルトでは、変更されたオブジ
   ェクトはシェルフに代入されたとき *だけ* 書き込まれます (使用例 参照
   )。 オプションの *writeback* パラメータが  "True" に設定されている
   場合は、アクセスされたすべてのエントリはメモリ上にキャッシュされ、
   "sync()" および "close()" を呼び出した際に書き戻されます; この機能
   は永続的な辞書上の可変の要素に対する変更を容易にしますが、多数のエ
   ントリがアクセスされた場合、膨大な量のメモリがキャッシュのために消
   費され、アクセスされた全てのエントリを書き戻す (アクセスされたエン
   トリが可変であるか、あるいは実際に変更されたかを決定する方法は存在
   しないのです) ために、ファイルを閉じる操作が非常に低速になります。

   Like file objects, shelve objects should be closed explicitly to
   ensure that the persistent data is flushed to disk.

警告: "shelve" モジュールは裏で "pickle" を使っているので、信頼でき
  ないソ ースからシェルフを読み込むのは危険です。 pickle と同じく、
  shelf の 読み込みでも任意のコードを実行できるからです。

Shelf objects support most of the methods supported by dictionaries.
This eases the transition from dictionary based scripts to those
requiring persistent storage.

Note, the Python 3 transition methods ("viewkeys()", "viewvalues()",
and "viewitems()") are not supported.

追加でサポートされるメソッドが二つあります:

Shelf.sync()

   シェルフが *writeback* を "True" にセットして開かれている場合に、キ
   ャッシュ中の全てのエントリを書き戻します。また可能な場合は、キャッ
   シュを空にしてディスク上の永続的な辞書を同期します。このメソッドは
   シェルフを "close()" によって閉じるとき自動的に呼び出されます。

Shelf.close()

   永続的な *辞書* オブジェクトを同期して閉じます。既に閉じられている
   シェルフに対して呼び出すと "ValueError" を出し失敗します。

参考: 通常の辞書に近い速度をもち、いろいろなストレージフォーマットに
  対応し た、 永続化辞書のレシピ 。


制限事項
========

* The choice of which database package will be used (such as "dbm",
  "gdbm" or "bsddb") depends on which interface is available.
  Therefore it is not safe to open the database directly using "dbm".
  The database is also (unfortunately) subject to the limitations of
  "dbm", if it is used — this means that (the pickled representation
  of) the objects stored in the database should be fairly small, and
  in rare cases key collisions may cause the database to refuse
  updates.

* "shelve" モジュールは、シェルフに置かれたオブジェクトの *並列した*
  読み出し/書き込みアクセスをサポートしません (複数の同時読み出しアク
  セスは安全です)。あるプログラムが書き込みのために開かれたシェルフを
  持っているとき、他のプログラムはそのシェルフを読み書きのために開いて
  はいけません。この問題を解決するために Unix のファイルロック機構を使
  うことができますが、この機構は Unix のバージョン間で異なり、使われて
  いるデータベースの実装について知識が必要となります。

class shelve.Shelf(dict, protocol=None, writeback=False)

   A subclass of "UserDict.DictMixin" which stores pickled values in
   the *dict* object.

   By default, version 0 pickles are used to serialize values.  The
   version of the pickle protocol can be specified with the *protocol*
   parameter. See the "pickle" documentation for a discussion of the
   pickle protocols.

   バージョン 2.3 で変更: The *protocol* parameter was added.

   *writeback* パラメータが "True" に設定されていれば、アクセスされた
   すべてのエントリはメモリ上にキャッシュされ、ファイルを閉じる際に
   *dict* に書き戻されます; この機能により、可変のエントリに対して自然
   な操作が可能になりますが、さらに多くのメモリを消費し、辞書をファイ
   ルと同期して閉じる際に長い時間がかかるようになります。

class shelve.BsdDbShelf(dict, protocol=None, writeback=False)

   A subclass of "Shelf" which exposes "first()", "next()",
   "previous()", "last()" and "set_location()" which are available in
   the "bsddb" module but not in other database modules.  The *dict*
   object passed to the constructor must support those methods.  This
   is generally accomplished by calling one of "bsddb.hashopen()",
   "bsddb.btopen()" or "bsddb.rnopen()".  The optional *protocol* and
   *writeback* parameters have the same interpretation as for the
   "Shelf" class.

class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)

   A subclass of "Shelf" which accepts a *filename* instead of a dict-
   like object.  The underlying file will be opened using
   "anydbm.open()".  By default, the file will be created and opened
   for both read and write.  The optional *flag* parameter has the
   same interpretation as for the "open()" function.  The optional
   *protocol* and *writeback* parameters have the same interpretation
   as for the "Shelf" class.


使用例
======

インタフェースは以下のコードに集約されています ("key" は文字列で、
"data" は任意のオブジェクトです):

   import shelve

   d = shelve.open(filename) # open -- file may get suffix added by low-level
                             # library

   d[key] = data   # store data at key (overwrites old data if
                   # using an existing key)
   data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
                   # such key)
   del d[key]      # delete data stored at key (raises KeyError
                   # if no such key)
   flag = d.has_key(key)   # true if the key exists
   klist = d.keys() # a list of all existing keys (slow!)

   # as d was opened WITHOUT writeback=True, beware:
   d['xx'] = range(4)  # this works as expected, but...
   d['xx'].append(5)   # *this doesn't!* -- d['xx'] is STILL range(4)!

   # having opened d without writeback=True, you need to code carefully:
   temp = d['xx']      # extracts the copy
   temp.append(5)      # mutates the copy
   d['xx'] = temp      # stores the copy right back, to persist it

   # or, d=shelve.open(filename,writeback=True) would let you just code
   # d['xx'].append(5) and have it work as expected, BUT it would also
   # consume more memory and make the d.close() operation slower.

   d.close()       # close it

参考:

  Module "anydbm"
     Generic interface to "dbm"-style databases.

  Module "bsddb"
     BSD "db" database interface.

  Module "dbhash"
     Thin layer around the "bsddb" which provides an "open()" function
     like the other database modules.

  "dbm" モジュール
     Standard Unix database interface.

  Module "dumbdbm"
     Portable implementation of the "dbm" interface.

  Module "gdbm"
     GNU database interface, based on the "dbm" interface.

  "pickle" モジュール
     "shelve" によって使われるオブジェクト整列化機構。

  Module "cPickle"
     High-performance version of "pickle".
