14

そのため、辞書を永続ファイルに保存したいと考えています。通常の辞書メソッドを使用して、そのファイルの辞書からエントリを追加、印刷、または削除する方法はありますか?

cPickleを使用して辞書を保存してロードできるようですが、そこからどこに取得すればよいかわかりません。

4

8 に答える 8

18

キー (必ずしも値ではない) が文字列の場合、shelf標準ライブラリ モジュールは、必要なことを非常にシームレスに実行します。

于 2009-08-04T18:17:27.153 に答える
10

JSON を使用する

ピートの答えと同様に、私は JSON を使用するのが好きです。JSON は Python のデータ構造に非常によく対応し、非常に読みやすいからです。

データの永続化は簡単です:

>>> import json
>>> db = {'hello': 123, 'foo': [1,2,3,4,5,6], 'bar': {'a': 0, 'b':9}}
>>> fh = open("db.json", 'w')
>>> json.dump(db, fh)

それをロードすることはほぼ同じです:

>>> import json
>>> fh = open("db.json", 'r')
>>> db = json.load(fh)
>>> db
{'hello': 123, 'bar': {'a': 0, 'b': 9}, 'foo': [1, 2, 3, 4, 5, 6]}
>>> del new_db['foo'][3]
>>> new_db['foo']
[1, 2, 3, 5, 6]

さらに、IIRC は pickle よりも低速ですが、JSON の読み込みはshelveおよび と同じセキュリティ問題に悩まされることはありません。pickle

すべての操作に書き込みたい場合:

すべての操作を節約したい場合は、Python dict オブジェクトをサブクラス化できます。

import os
import json

class DictPersistJSON(dict):
    def __init__(self, filename, *args, **kwargs):
        self.filename = filename
        self._load();
        self.update(*args, **kwargs)

    def _load(self):
        if os.path.isfile(self.filename) 
           and os.path.getsize(self.filename) > 0:
            with open(self.filename, 'r') as fh:
                self.update(json.load(fh))

    def _dump(self):
        with open(self.filename, 'w') as fh:
            json.dump(self, fh)

    def __getitem__(self, key):
        return dict.__getitem__(self, key)

    def __setitem__(self, key, val):
        dict.__setitem__(self, key, val)
        self._dump()

    def __repr__(self):
        dictrepr = dict.__repr__(self)
        return '%s(%s)' % (type(self).__name__, dictrepr)

    def update(self, *args, **kwargs):
        for k, v in dict(*args, **kwargs).items():
            self[k] = v
        self._dump()

次のように使用できます。

db = DictPersistJSON("db.json")
db["foo"] = "bar" # Will trigger a write

これは非常に非効率的ですが、すぐに軌道に乗ることができます。

于 2014-04-17T15:38:26.723 に答える
6

プログラムのロード時にファイルから unpickle し、プログラムの実行中にメモリ内の通常の辞書として変更し、プログラムの終了時にファイルに pickle しますか? ここで何を求めているのか正確にはわかりません。

于 2009-08-04T18:13:07.193 に答える
1

私のお気に入りの方法 (標準の python 辞書関数を使用しない): PyYamlを使用して YAML ファイルを読み書きします。 詳細については、この回答を参照してください。ここに要約されています。

YAML ファイル「employment.yml」を作成します。

new jersey:
  mercer county:
    pumbers: 3
    programmers: 81
  middlesex county:
    salesmen: 62
    programmers: 81
new york:
  queens county:
    plumbers: 9
    salesmen: 36

ステップ 3: Python で読む

import yaml
file_handle = open("employment.yml")
my__dictionary = yaml.safe_load(file_handle)
file_handle.close()

これで my__dictionary にすべての値が含まれるようになりました。その場でこれを行う必要がある場合は、YAML を含む文字列を作成し、yaml.safe_load で解析します。

于 2009-08-04T19:09:22.230 に答える
1

キーと値に の機能する実装があると仮定するとrepr、1 つの解決策は、辞書 ( repr(dict)) の文字列表現をファイルに保存することです。eval関数 ( )を使用してロードできますeval(inputstring)。この手法には主に 2 つの欠点があります。

1) 使用できない repr の実装を持つ型では機能しません (または機能しているように見えても失敗する場合もあります)。何が起こっているのか、少なくとも注意を払う必要があります。

2) ファイル ロード メカニズムは、基本的に Python コードを直接実行するものです。入力を完全に制御しない限り、セキュリティには適していません。

利点が 1 つあります。驚くほど簡単です。

于 2009-08-04T18:24:22.460 に答える
1

shelve(モジュールで許可されているように) 文字列のみをキーとして使用するだけでは不十分な場合は、 FileDictを使用してこの問題を解決することをお勧めします。

于 2012-08-21T16:02:21.880 に答える
0

ピクルスには1つの欠点があります。ディクショナリをディスクから頻繁に読み書きする必要があり、ディクショナリが大きい場合、コストがかかる可能性があります。pickle は物を (全体) ダンプします。unpickle は (全体として) ものを準備します。

小さな辞書を処理する必要がある場合は、ピクルスで問題ありません。より複雑なものを使用する場合は、berkelydb を使用してください。基本的に、キーと値のペアを格納するように作られています。

于 2009-08-04T19:03:14.143 に答える