“シェルフ (shelf, 棚)” は辞書に似た永続性を持つオブジェクトです。 “dbm” データベースとの違いは、シェルフの値 (キーではありません!) は実質上どんな Python オブジェクトにも — pickle モジュールが扱えるなら何でも — できるということです。これにはほとんどのクラスインスタンス、再帰的なデータ型、沢山の共有されたサブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。
永続的な辞書を開きます。指定された filename は、根底にあるデータベースの基本ファイル名となります。副作用として、 filename には拡張子がつけられる場合があり、ひとつ以上のファイルが生成される可能性もあります。デフォルトでは、根底にあるデータベースファイルは読み書き可能なように開かれます。オプションの flag パラメタは anydbm.open() における flag パラメタと同様に解釈されます。
デフォルトでは、値を整列化する際にはバージョン 0 の pickle 化が用いられます。pickle 化プロトコルのバージョンは protocol パラメタで指定することができます。
バージョン 2.3 で変更: protocol パラメタが追加されました。
Python の意味論から、シェルフには永続的な辞書の可変エントリに対する変更を知る術がありません。デフォルトでは、変更されたオブジェクトはシェルフに代入されたとき だけ 書き込まれます (使用例 参照)。オプションの writeback パラメタが True に設定されていれば、アクセスされたすべてのエントリはメモリ上にキャッシュされ、 sync() および close() を呼び出した際に書き戻されます。この機能は永続的な辞書上の可変の要素に対する変更を容易にしますが、多数のエントリがアクセスされた場合、膨大な量のメモリがキャッシュのために消費され、アクセスされた全てのエントリを書き戻す (アクセスされたエントリが可変であるか、あるいは実際に変更されたかを決定する方法は存在しないのです) ために、ファイルを閉じる操作を非常に低速にしてしまいます。
シェルフオブジェクトは辞書がサポートする全てのメソッドをサポートしています。これにより、辞書ベースのスクリプトから永続的な記憶媒体を必要とするスクリプトに容易に移行できるようになります。
追加でサポートされるメソッドが二つあります:
シェルフが writeback を True にセットして開かれている場合に、キャッシュ中の全てのエントリを書き戻します。また容易にできるならば、キャッシュを空にしてディスク上の永続的な辞書を同期します。このメソッドはシェルフを close() によって閉じるとき自動的に呼び出されます。
永続的な 辞書 オブジェクトを同期して閉じます。既に閉じられているシェルフに対して呼び出すと ValueError に終わります。
参考
通常の辞書に近い速度をもち、いろいろなストレージフォーマットに対応した、 永続化辞書のレシピ
UserDict.DictMixin のサブクラスで、pickle 化された値を dict オブジェクトに保存します。
デフォルトでは、値を整列化する際にはバージョン 0 の pickle 化が用いられます。pickle 化プロトコルのバージョンは protocol パラメタで指定することができます。pickle 化プロトコルについては pickle のドキュメントを参照してください。
バージョン 2.3 で変更: protocol パラメタが追加されました。
writeback パラメタが True に設定されていれば、アクセスされたすべてのエントリはメモリ上にキャッシュされ、ファイルを閉じる際に書き戻されます; この機能により、可変のエントリに対して自然な操作が可能になりますが、さらに多くのメモリを消費し、辞書をファイルと同期して閉じる際に長い時間がかかるようになります。
Shelf のサブクラスで、 first(), next(), previous(), last(), set_location() メソッドを公開しています。これらのメソッドは bsddb モジュールでは利用可能ですが、他のデータベースモジュールでは利用できません。コンストラクタに渡された dict オブジェクトは上記のメソッドをサポートしていなくてはなりません。通常は、 bsddb.hashopen(), bsddb.btopen() または bsddb.rnopen() のいずれかを呼び出して得られるオブジェクトが条件を満たしています。オプションの protocol および writeback パラメタは Shelf クラスにおけるパラメタと同様に解釈されます。
Shelf のサブクラスで、辞書様オブジェクトの代わりに filename を受理します。根底にあるファイルは anydbm.open() を使って開かれます。デフォルトでは、ファイルは読み書き可能な状態で開かれます。オプションの flag パラメタは open() 関数におけるパラメタと同様に解釈されます。オプションの protocol および writeback パラメタは Shelf クラスにおけるパラメタと同様に解釈されます。
インタフェースは以下のコードに集約されています (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
参考