dbm

永井 忠一 2024.9.29


Perl と Python から利用

バージョン確認

$ perl --version

This is perl 5, version 38, subversion 2 (v5.38.2) built for x86_64-linux-gnu-thread-multi
(with 44 registered patches, see perl -V for more detail)

Copyright 1987-2023, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl".  If you have access to the
Internet, point your browser at https://www.perl.org/, the Perl Home Page.

              
$ python3 --version Python 3.12.3

DBM 形式

PerlPython
use strict;
use warnings;

use DB_File;

tie(my %data, "DB_File", "data_pl") or die;

$data{"test key"} = "test record";

untie(%data);
import dbm

data = dbm.open('data_py', 'c')

data['test key'] = 'test record'

data.close()

確認

$ file data_pl
data_pl: Berkeley DB (Hash, version 9, native byte-order)
              
$ file data_py data_py: GNU dbm 1.x or ndbm database, little endian, 64-bit

GDBM_File モジュール

Perl で gdbm ライブラリを利用

Perl
use strict;
use warnings;

use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_WRCREAT, 0666) or die;

$data{"test key"} = "test record";

untie(%data);

(Python で gdbm を明示するには「import dbm.gnu」とする)

GNU dbm 形式を使うことで、Perl と Python から同じ DBM ファイルを使用することができる

Perl モジュールPython モジュール
Berkeley DBDB_Filebsddb(廃止されている)
GNU gdbmGDBM_Filedbm.gnu(gdbm から改名)

(以降の例では gdbm を共通利用)


dbm へのアクセス

Perl では、tie() 関数でハッシュに結び付ける。Python では、辞書と同じように利用できる

(Python では、実際には(dict ではなく、)「_gdbm.gdbm」)

IPython
$ ipython3
Python 3.12.3 (main, Jul 31 2024, 17:43:48) [GCC 13.2.0]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.20.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import dbm

In [2]: data = dbm.open('data', 'r')

In [3]: type(data)
Out[3]: _gdbm.gdbm

(IPython で、Perl の出力ファイルを(読み取り専用モードで)オープンして、型を確認)

エントリー数の確認

(上記 例の出力結果のファイルを、(読み取り専用モードで)利用)

PerlPython
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_READER, 0666) or die;

print(my $len = keys(%data) . "\n");

untie(%data);
import dbm

data = dbm.open('data', 'r')

print(len(data))

data.close()

(Perl では、キーの一覧の配列を取得して、配列をスカラーコンテキストで評価)

削除

(上記 例の出力結果のファイルを、(読み書きモードで)利用)

キーを指定して削除

PerlPython
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_WRITER, 0666) or die;

delete $data{"test key"};

untie(%data);
import dbm

data = dbm.open('data', 'w')

try:
    del data['test key']
except KeyError:
    pass

data.close()

(Python では、存在しないキーへのアクセスは KeyError となる)

全要素の削除

Perl
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_WRITER, 0666) or die;

%data = ();

untie(%data);

(Python では clear() メソッドを使用するが、実装されるのは(ドキュメントによると)version 3.13 から)

キーの列挙

PerlPython
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_WRCREAT, 0666) or die;

$data{"test key"} = "test record";
$data{"test key 2"} = "test record 2";
$data{"test key 3"} = "test record 3";

foreach my $ite (keys(%data)) {
    print("$ite\n");
}

untie(%data);
import dbm

data = dbm.open('data', 'c')

data['test key'] = 'test record'
data['test key 2'] = 'test record 2'
data['test key 3'] = 'test record 3'

for ite in data.keys():
    print(ite.decode())

data.close()

(Python では、keys() メソッドが返すのは、バイト列のリスト)

IPython
In [1]: import dbm

In [2]: data = dbm.open('data', 'r')

In [3]: print(data.keys()[0])
b'test key 2'

In [4]: type(data.keys()[0])
Out[4]: bytes

(IPython で、出力結果のファイルを利用して、キーの型を確認)

キーの存在確認

(上記 例の出力結果のファイルを、(読み取り専用モードで)利用)

PerlPython
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_READER, 0666) or die;

print(exists($data{"test key"}) . "\n");

untie(%data);
import dbm

data = dbm.open('data', 'r')

print('test key' in data)

data.close()

(Perl では exists() 関数、Python では in 演算子を使う)

値の参照

キーを指定

PerlPython
use strict;
use warnings;
use GDBM_File;

tie(my %data, "GDBM_File", "data", GDBM_READER, 0666) or die;

print($data{"test key"} . "\n");

untie(%data);
import dbm

data = dbm.open('data', 'r')

print(data['test key'].decode())

data.close()

(Python では、値はバイト列)

IPython
In [1]: import dbm

In [2]: data = dbm.open('data', 'r')

In [3]: print(data['test key'])
b'test record'

In [4]: type(data['test key'])
Out[4]: bytes

(IPython で、出力結果のファイルを利用して、値の型を確認)


参照したドキュメント

(Perl と Python とも、dbm は、標準モジュール、標準ライブラリにある)


© 2024 Tadakazu Nagai