Pythonのshelveモジュール解説:辞書感覚で使えるデータ永続化
shelveモジュールとは
Pythonの標準ライブラリに含まれるshelveモジュールは、本格的なリレーショナルデータベースを導入するまでもない規模のデータを、手軽に永続化したいときに役立つシンプルかつ効果的なツールです。
このモジュールで定義される「shelf(シェルフ)」オブジェクトは、通常の辞書(dict)とほぼ同じ感覚で操作できますが、その内容はディスク上のファイルに保存されるため、プログラムを終了してもデータが失われません。UNIX系システムで使われるdbmデータベースに似たファイルが生成される点も特徴です。
キーに指定できるのは文字列型のみという制限がありますが、値にはpickle化(シリアライズ)可能な任意のオブジェクトを格納できます。数値や文字列はもちろん、リスト・辞書・タプル、さらにはユーザー定義クラスのインスタンスまで保存可能です。
shelveモジュールを構成する3つのクラス
| No. | クラス名と説明 |
|---|---|
| 1 | Shelf shelf実装の基底クラスです。dictライクなオブジェクトを使って初期化します。 |
| 2 | BsdDbShelf Shelfクラスのサブクラスです。コンストラクタに渡すdictオブジェクトは、first()・next()・previous()・last()・set_location() の各メソッドをサポートしている必要があります。 |
| 3 | DbfilenameShelf こちらもShelfクラスのサブクラスですが、dictオブジェクトではなくファイル名を引数として受け取ります。 |
open()関数でShelfオブジェクトを作成する
Shelfオブジェクトを最も簡単に生成する方法は、shelveモジュールに定義された open() 関数を使うことです。この関数はDbfilenameShelfオブジェクトを返します。
open(filename, flag='c', protocol=None, writeback=False)
各パラメータの意味
- filename:作成されるデータベースファイルの名前を指定します。
- flag:ファイルの開き方を指定します。デフォルトは 'c' です。
- 'c' … 読み書き可(デフォルト)
- 'w' … 書き込み専用
- 'r' … 読み取り専用
- 'n' … 新規作成して読み書き
- protocol:pickleプロトコルのバージョンを指定します。Noneの場合はデフォルトのプロトコルが使用されます。
- writeback:デフォルトはFalse。Trueにするとアクセスされたエントリがメモリ上にキャッシュされ、sync()およびclose()の呼び出し時にまとめて書き戻されます。ただしキャッシュ管理のオーバーヘッドがあるため、処理速度が低下する可能性があります。
基本的な使い方:データベースへの保存
次のコードは、データベースを作成し、辞書形式でエントリを保存する例です。
import shelve
s = shelve.open("test")
s['name'] = "Ajay"
s['age'] = 23
s['marks'] = 75
s.close()このコードを実行すると、カレントディレクトリに test.dir(使用するdbm実装によっては test.dat や test.db などのファイル)が作成され、キーと値のペアがハッシュ化された形で保存されます。
Shelfオブジェクトの主なメソッド
| No. | メソッドと説明 |
|---|---|
| 1 | close() 永続化された辞書オブジェクトを同期して閉じます。 |
| 2 | sync() writeback=True で開いた場合に、キャッシュ内の全エントリを書き戻します。 |
| 3 | get() 指定したキーに関連付けられた値を返します。 |
| 4 | items() キーと値のペアからなるタプルのリスト(ビュー)を返します。 |
| 5 | keys() shelfのキーのリスト(ビュー)を返します。 |
| 6 | pop() 指定したキーを削除し、対応する値を返します。 |
| 7 | update() 別のdictやイテラブルからshelfを更新します。 |
| 8 | values() shelfの値のリスト(ビュー)を返します。 |
値の取得と更新
特定のキーの値にアクセスするには、通常の辞書と同じように記述します。
>>> s = shelve.open('test')
>>> s['age']
23
>>> s['age'] = 25
>>> s.get('age')
25s['key'] = 変更後の値 のように再代入するか、open()時に writeback=True を指定してください。items()・keys()・values()による一覧取得
これらのメソッドはビューオブジェクトを返すため、list()で変換すると中身を確認しやすくなります。
>>> list(s.items())
[('name', 'Ajay'), ('age', 25), ('marks', 75)]
>>> list(s.keys())
['name', 'age', 'marks']
>>> list(s.values())
['Ajay', 25, 75]pop()でキーと値のペアを削除する
>>> s.pop('marks')
75
>>> list(s.items())
[('name', 'Ajay'), ('age', 25)]marks-75 のペアが削除されたことが確認できます。
update()で別の辞書をマージする
別の辞書の要素をshelfに統合するには update() メソッドを使用します。
>>> d = {'salary': 10000, 'designation': 'manager'}
>>> s.update(d)
>>> list(s.items())
[('name', 'Ajay'), ('age', 25), ('salary', 10000), ('designation', 'manager')]まとめ
本記事では、永続的な辞書オブジェクトを手軽に扱えるshelveモジュールについて解説しました。小規模なデータ保存やアプリケーションの設定情報の管理など、データベースサーバーを用意するほどではないケースにおいて、shelveは非常に便利な選択肢となります。ぜひ実際の開発で活用してみてください。
-
Pythonのオブジェクト比較を徹底解説:「is」と「==」演算子の違い
本記事では、Pythonにおけるオブジェクト比較の方法として、「is」演算子と等価演算子「==」の違いについて詳しく解説します。 この2つの演算子は似ているようで、実はまったく異なる役割を持っています。それぞれの動作の仕組みを正しく理解することは、バグの少ないPythonコードを書く上で非常に重要です。 「==」と「is」の基本的な違い 等価演算子(==)は、渡されたオブジェクトの値が等しいかどうかを判定します。つまり、2つのオブジェクトがメモリ上のどこに格納されていようと、中身の内容が同じであれば「等しい」とみなされます。 一方、is 演算子は、2つのオブジェクトが同一の参照(同じメモリ上の
-
Pythonのtimetuple()メソッドとは?struct_timeオブジェクトの基本と使い方
Pythonでは、datetime.dateインスタンスが持つtimetuple()メソッドを呼び出すと、time.struct_time型のオブジェクトが返されます。struct_timeは名前付きタプル(named tuple)の一種で、インデックス番号だけでなく、属性名を使って各フィールドにアクセスできるのが特徴です。struct_timeオブジェクトの構成要素struct_timeオブジェクトには、日付と時刻の両方を表す属性が含まれており、さらに夏時間(DST:Daylight Saving Time)が有効かどうかを示すフラグも持っています。timetuple()関数が返す名前付きタ