11.4。 棚 —Pythonオブジェクトの永続性
ソースコード: :source: `Lib / shelve.py`
「棚」は、永続的な辞書のようなオブジェクトです。 「dbm」データベースとの違いは、シェルフ内の値(キーではありません!)が本質的に任意のPythonオブジェクト、つまり pickle モジュールが処理できるものであれば何でもかまいません。 これには、ほとんどのクラスインスタンス、再帰データ型、および多くの共有サブオブジェクトを含むオブジェクトが含まれます。 キーは通常の文字列です。
- shelve.open(filename, flag='c', protocol=None, writeback=False)
永続辞書を開きます。 指定されたファイル名は、基礎となるデータベースのベースファイル名です。 副作用として、ファイル名に拡張子が追加され、複数のファイルが作成される場合があります。 デフォルトでは、基になるデータベースファイルは読み取りと書き込みのために開かれます。 オプションの flag パラメーターは、 anydbm.open()の flag パラメーターと同じ解釈になります。
デフォルトでは、バージョン0のピクルスが値のシリアル化に使用されます。 ピクルスプロトコルのバージョンは、 protocol パラメーターで指定できます。
バージョン2.3で変更: プロトコルパラメーターが追加されました。
Pythonのセマンティクスのため、シェルフは、変更可能な永続ディクショナリエントリがいつ変更されたかを知ることができません。 デフォルトでは、変更されたオブジェクトは、シェルフに割り当てられたときにのみと書き込まれます(例を参照)。 オプションの writeback パラメータが
True
に設定されている場合、アクセスされたすべてのエントリもメモリにキャッシュされ、 sync()および close()に書き戻されます。 ; これにより、永続ディクショナリ内の可変エントリを変更するのが便利になりますが、多くのエントリにアクセスすると、キャッシュに大量のメモリを消費する可能性があり、アクセスしたすべてのエントリが書き戻されるため、クローズ操作が非常に遅くなる可能性があります(アクセスされたエントリが変更可能であるか、実際に変更されたかを判断する方法はありません)。ファイルオブジェクトと同様に、永続データがディスクにフラッシュされるように、シェルフオブジェクトを明示的に閉じる必要があります。
警告
shelve モジュールは pickle によってサポートされているため、信頼できないソースからシェルフをロードすることは安全ではありません。 pickleと同様に、シェルフをロードすると任意のコードが実行される可能性があります。
シェルフオブジェクトは、ディクショナリでサポートされているほとんどのメソッドをサポートしています。 これにより、辞書ベースのスクリプトから永続ストレージを必要とするスクリプトへの移行が容易になります。
Python 3遷移メソッド( viewkeys()、 viewvalues()、および viewitems())はサポートされていないことに注意してください。
2つの追加の方法がサポートされています。
- Shelf.sync()
- writeback を True に設定してシェルフを開いた場合は、キャッシュ内のすべてのエントリを書き戻します。 また、可能であれば、キャッシュを空にし、ディスク上の永続ディクショナリを同期します。 これは、 close()でシェルフが閉じられると自動的に呼び出されます。
- Shelf.close()
- 永続的な dict オブジェクトを同期して閉じます。 閉じたシェルフでの操作は、
ValueError
で失敗します。
11.4.1。 制限
- 使用するデータベースパッケージ( dbm 、 gdbm 、 bsddb など)の選択は、使用可能なインターフェイスによって異なります。 したがって、 dbm を使用してデータベースを直接開くことは安全ではありません。 データベースは、使用される場合、(残念ながら) dbm の制限も受けます。これは、データベースに格納されているオブジェクト(のピクルス表現)がかなり小さく、まれにキーになることを意味します。衝突により、データベースが更新を拒否する場合があります。
- shelve モジュールは、シェルフされたオブジェクトへの同時読み取り/書き込みアクセスをサポートしていません。 (複数の同時読み取りアクセスは安全です。)プログラムに書き込み用に開いているシェルフがある場合、他のプログラムでは読み取りまたは書き込み用に開いてはなりません。 これを解決するにはUnixファイルロックを使用できますが、これはUnixバージョンによって異なり、使用するデータベース実装に関する知識が必要です。
- class shelve.Shelf(dict, protocol=None, writeback=False)
UserDict.DictMixin のサブクラスで、ピクルス化された値を dict オブジェクトに格納します。
デフォルトでは、バージョン0のピクルスが値のシリアル化に使用されます。 ピクルスプロトコルのバージョンは、 protocol パラメーターで指定できます。 ピクルスプロトコルの説明については、 pickle のドキュメントを参照してください。
バージョン2.3で変更: プロトコルパラメーターが追加されました。
writeback パラメータが
True
の場合、オブジェクトはアクセスされたすべてのエントリのキャッシュを保持し、同期時と終了時に dict に書き戻します。 これにより、可変エントリでの自然な操作が可能になりますが、より多くのメモリを消費し、同期とクローズに長い時間がかかる可能性があります。
- class shelve.BsdDbShelf(dict, protocol=None, writeback=False)
first()
、next()
、previous()
、last()
、set_location()
を公開する Shelf のサブクラス bsddb モジュールですが、他のデータベースモジュールにはありません。 コンストラクターに渡される dict オブジェクトは、これらのメソッドをサポートする必要があります。 これは通常、 bsddb.hashopen()、 bsddb.btopen()、または bsddb.rnopen()のいずれかを呼び出すことによって実現されます。 オプションのプロトコルおよびライトバックパラメーターは、シェルフクラスの場合と同じ解釈になります。
- class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False)
- dictのようなオブジェクトの代わりに filename を受け入れる Shelf のサブクラス。 基になるファイルは、 anydbm.open()を使用して開かれます。 デフォルトでは、ファイルは読み取りと書き込みの両方で作成および開かれます。 オプションの flag パラメーターは、 open()関数の場合と同じ解釈になります。 オプションのプロトコルおよびライトバックパラメーターは、シェルフクラスの場合と同じ解釈になります。
11.4.2。 例
インターフェイスを要約すると(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
も参照してください
- モジュール anydbm
dbm
スタイルのデータベースへの汎用インターフェース。- モジュール bsddb
- BSD
db
データベースインターフェース。 - モジュール dbhash
- 他のデータベースモジュールと同様に open()関数を提供する bsddb の周りの薄層。
- モジュール dbm
- 標準のUnixデータベースインターフェイス。
- モジュール dumbdbm
dbm
インターフェースのポータブル実装。- モジュール gdbm
dbm
インターフェースに基づくGNUデータベースインターフェース。- モジュールピクル
- シェルフで使用されるオブジェクトのシリアル化。
- モジュール cPickle
- picle の高性能バージョン。