shelve
--- Python オブジェクトの永続化¶
ソースコード: Lib/shelve.py
"シェルフ (shelf, 棚)" は辞書に似た永続性を持つオブジェクトです。 "dbm" データベースとの違いは、シェルフの値 (キーではありません!) は実質上どんな Python オブジェクトにも --- pickle
モジュールが扱えるなら何でも --- できるということです。これにはほとんどのクラスインスタンス、再帰的なデータ型、沢山の共有されたサブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。
- shelve.open(filename, flag='c', protocol=None, writeback=False, *, serializer=None, deserializer=None)¶
永続的な辞書を開きます。指定された filename は、根底にあるデータベースの基本ファイル名となります。副作用として、 filename には拡張子がつけられる場合があり、ひとつ以上のファイルが生成される可能性もあります。デフォルトでは、根底にあるデータベースファイルは読み書き可能なように開かれます。オプションの flag パラメータは
dbm.open()
における flag パラメータと同様に解釈されます。By default, pickles created with
pickle.DEFAULT_PROTOCOL
are used to serialize values. The version of the pickle protocol can be specified with the protocol parameter.Python の意味論により、シェルフには永続的な辞書の可変エントリがいつ変更されたかを知る術がありません。 デフォルトでは、変更されたオブジェクトはシェルフに代入されたとき だけ 書き込まれます (使用例 参照)。 オプションの writeback パラメータが
True
に設定されている場合は、アクセスされたすべてのエントリはメモリ上にキャッシュされ、sync()
およびclose()
を呼び出した際に書き戻されます; この機能は永続的な辞書上の可変の要素に対する変更を容易にしますが、多数のエントリがアクセスされた場合、膨大な量のメモリがキャッシュのために消費され、アクセスされた全てのエントリを書き戻す (アクセスされたエントリが可変であるか、あるいは実際に変更されたかを決定する方法は存在しないのです) ために、ファイルを閉じる操作が非常に低速になります。By default,
shelve
usespickle.dumps()
andpickle.loads()
for serializing and deserializing. This can be changed by supplying serializer and deserializer, respectively.The serializer argument must be a callable which takes an object
obj
and the protocol as inputs and returns the representationobj
as a bytes-like object; the protocol value may be ignored by the serializer.The deserializer argument must be callable which takes a serialized object given as a
bytes
object and returns the corresponding object.A
ShelveError
is raised if serializer is given but deserializer is not, or vice-versa.バージョン 3.10 で変更:
pickle.DEFAULT_PROTOCOL
is now used as the default pickle protocol.バージョン 3.11 で変更: Accepts path-like object for filename.
バージョン 3.15.0a0 (unreleased) で変更: Accepts custom serializer and deserializer functions in place of
pickle.dumps()
andpickle.loads()
.注釈
シェルフが自動的に閉じることに依存しないでください; それがもう必要ない場合は常に
close()
を明示的に呼ぶか、shelve.open()
をコンテキストマネージャとして使用してください:with shelve.open('spam') as db: db['eggs'] = 'eggs'
警告
shelve
モジュールは裏で pickle
を使っているので、信頼できないソースからシェルフを読み込むのは危険です。 pickle と同じく、 shelf の読み込みでも任意のコードを実行できるからです。
Shelf objects support most of methods and operations supported by dictionaries
(except copying, constructors and operators |
and |=
). This eases the
transition from dictionary based scripts to those requiring persistent storage.
追加でサポートされるメソッドが二つあります:
- Shelf.sync()¶
Write back all entries in the cache if the shelf was opened with writeback set to
True
. Also empty the cache and synchronize the persistent dictionary on disk, if feasible. This is called automatically whenreorganize()
is called or the shelf is closed withclose()
.
- Shelf.reorganize()¶
Calls
sync()
and attempts to shrink space used on disk by removing empty space resulting from deletions.Added in version 3.15.0a0 (unreleased).
- Shelf.close()¶
永続的な 辞書 オブジェクトを同期して閉じます。既に閉じられているシェルフに対して呼び出すと
ValueError
を出し失敗します。
参考
Persistent dictionary recipe with widely supported storage formats and having the speed of native dictionaries.
制限事項¶
どのデータベースパッケージが使われるか (例えば
dbm.ndbm
、dbm.gnu
) は、どのインターフェースが利用可能かに依存します。従って、データベースをdbm
を使って直接開く方法は安全ではありません。データベースはまた、dbm
が使われた場合 (不幸なことに) その制約に縛られます --- これはデータベースに記録されたオブジェクト (の pickle 化された表現) はかなり小さくなければならず、キー衝突が生じた場合に、稀にデータベースを更新することができなくなることを意味します。shelve
モジュールは、シェルフに置かれたオブジェクトの 並列した 読み出し/書き込みアクセスをサポートしません (複数の同時読み出しアクセスは安全です)。あるプログラムが書き込みのために開かれたシェルフを持っているとき、他のプログラムはそのシェルフを読み書きのために開いてはいけません。この問題を解決するために Unix のファイルロック機構を使うことができますが、この機構は Unix のバージョン間で異なり、使われているデータベースの実装について知識が必要となります。On macOS
dbm.ndbm
can silently corrupt the database file on updates, which can cause hard crashes when trying to read from the database.Shelf.reorganize()
may not be available for all database packages and may temporarily increase resource usage (especially disk space) when called. Additionally, it will never run automatically and instead needs to be called explicitly.
- class shelve.Shelf(dict, protocol=None, writeback=False, keyencoding='utf-8', *, serializer=None, deserializer=None)¶
collections.abc.MutableMapping
のサブクラスで、 dict オブジェクト内にpickle化された値を保持します。By default, pickles created with
pickle.DEFAULT_PROTOCOL
are used to serialize values. The version of the pickle protocol can be specified with the protocol parameter. See thepickle
documentation for a discussion of the pickle protocols.writeback パラメータが
True
に設定されていれば、アクセスされたすべてのエントリはメモリ上にキャッシュされ、ファイルを閉じる際に dict に書き戻されます; この機能により、可変のエントリに対して自然な操作が可能になりますが、さらに多くのメモリを消費し、辞書をファイルと同期して閉じる際に長い時間がかかるようになります。keyencoding パラメータは、shelf の背後にある dict に対して使われる前にキーをエンコードするのに使用されるエンコーディングです。
The serializer and deserializer parameters have the same interpretation as in
open()
.Shelf
オブジェクトは、コンテキストマネージャとしても使用できます。この場合、with
ブロックが終了する際に、自動的に閉じられます。バージョン 3.2 で変更: keyencoding パラメータを追加; 以前はキーは常に UTF-8 でエンコードされていました。
バージョン 3.4 で変更: コンテキストマネージャーサポートが追加されました。
バージョン 3.10 で変更:
pickle.DEFAULT_PROTOCOL
is now used as the default pickle protocol.バージョン 3.15.0a0 (unreleased) で変更: Added the serializer and deserializer parameters.
- class shelve.BsdDbShelf(dict, protocol=None, writeback=False, keyencoding='utf-8', *, serializer=None, deserializer=None)¶
A subclass of
Shelf
which exposesfirst()
,next()
,previous()
,last()
andset_location()
methods. These are available in the third-partybsddb
module from pybsddb but not in other database modules. The dict object passed to the constructor must support those methods. This is generally accomplished by calling one ofbsddb.hashopen()
,bsddb.btopen()
orbsddb.rnopen()
. The optional protocol, writeback, keyencoding, serializer and deserializer parameters have the same interpretation as inopen()
.バージョン 3.15.0a0 (unreleased) で変更: Added the serializer and deserializer parameters.
- class shelve.DbfilenameShelf(filename, flag='c', protocol=None, writeback=False, *, serializer=None, deserializer=None)¶
A subclass of
Shelf
which accepts a filename instead of a dict-like object. The underlying file will be opened usingdbm.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 theopen()
function. The optional protocol, writeback, serializer and deserializer parameters have the same interpretation as inopen()
.バージョン 3.15.0a0 (unreleased) で変更: Added the serializer and deserializer parameters.
使用例¶
インターフェースは以下のコードに集約されています (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 = key in d # true if the key exists
klist = list(d.keys()) # a list of all existing keys (slow!)
# as d was opened WITHOUT writeback=True, beware:
d['xx'] = [0, 1, 2] # this works as expected, but...
d['xx'].append(3) # *this doesn't!* -- d['xx'] is STILL [0, 1, 2]!
# 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
Exceptions¶
- exception shelve.ShelveError¶
Exception raised when one of the arguments deserializer and serializer is missing in the
open()
,Shelf
,BsdDbShelf
andDbfilenameShelf
.The deserializer and serializer arguments must be given together.
Added in version 3.15.0a0 (unreleased).