25

現在、ファイルの解析にはコストがかかります。これにより、めったに更新されない、最大 400 個のキーと値のペアの辞書が生成されます。以前は、ファイルを解析し、それを辞書構文 (ie. ) などでテキスト ファイルに書き込み、dict = {'Adam': 'Room 430', 'Bob': 'Room 404'}その解析済み辞書を返すことだけを目的とした別の関数にコピー アンド ペーストする関数がありました。

したがって、その辞書を使用するすべてのファイルで、その関数をインポートし、変数に割り当てます。これが現在の辞書です。コードを明示的にコピーして貼り付ける必要のない、これを行うためのよりエレガントな方法があるかどうか疑問に思っていますか? データベースを使用する必要はないように思えますが、テキスト ファイルを使用すると、関数に追加する前に解析が正しく行われたかどうかを確認できるという利点がありました。しかし、私は提案を受け入れています。

4

8 に答える 8

60

それを JSON ファイルにダンプして、そこから必要な場所にロードしてみませんか?

import json

with open('my_dict.json', 'w') as f:
    json.dump(my_dict, f)

# elsewhere...

with open('my_dict.json') as f:
    my_dict = json.load(f)

JSON からの読み込みはかなり効率的です。

別のオプションとして を使用することもできますpickleが、JSON とは異なり、JSON が生成するファイルは人間が判読できるものではないため、以前の方法で気に入っていた視覚的な検証ができなくなります。

于 2012-08-06T00:32:13.347 に答える
21

なぜこれらすべてのシリアル化メソッドを台無しにするのですか? 既に Python dict としてファイルに書き込まれています (ただし、残念な名前は 'dict' です)。より適切な変数名 (「data」または「catalog」など) でデータを書き出すようにプログラムを変更し、ファイルを Python ファイル (たとえば、data.py) として保存します。次に、不器用なコピー/貼り付けや JSON/shelve などを行わずに、実行時にデータを直接インポートできます。解析:

from data import catalog
于 2012-08-06T06:11:05.430 に答える
6

多くの場合、おそらく JSON が正しい方法です。しかし、代替手段があるかもしれません。キーと値は常に文字列のように見えますが、そうですか? dbm/の使用を検討してanydbmください。これらは「データベース」ですが、辞書とほぼ同じように機能します。それらは、安価なデータ永続化に最適です。

>>> import anydbm
>>> dict_of_strings = anydbm.open('data', 'c')
>>> dict_of_strings['foo'] = 'bar'
>>> dict_of_strings.close()
>>> dict_of_strings = anydbm.open('data')
>>> dict_of_strings['foo']
'bar'
于 2012-08-06T01:07:54.790 に答える
5

キーがすべて文字列の場合は、shelveモジュールを使用できます

は永続的な辞書のようなオブジェクトです。「dbm」データベースとの違いは、シェルフ内の値(キーではありません!)が本質的に任意のPythonオブジェクト、つまりpickleモジュールが処理できるものであれば何でもかまいません。これには、ほとんどのクラスインスタンス、再帰データ型、および多くの共有サブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。

json他の言語のデータを使用する必要がある場合は、良い選択です

于 2012-08-06T01:31:46.573 に答える
3

shelveデータ構造はマッピングであるため、モジュールの使用を検討することをお勧めします。これは、 「カスタムデータベースを構築したい場合、どうすればよいですか」というタイトルの同様の質問に対する私の答えでした。私の別の回答には、オブジェクトデータベースを取得する方法という質問への使用を宣伝するサンプルコードも少しあります。

ActiveStateには、 csv、json、およびpickle出力ファイル形式をサポートする高評価のPersistentDictレシピがあります。これらの3つの形式はすべてCで実装されているため(レシピ自体は純粋なPythonですが)、かなり高速です。したがって、開いたときにファイル全体をメモリに読み込むという事実は許容できる場合があります。

于 2012-08-06T01:48:40.800 に答える
3

ストレージ効率が重要な場合は、Pickle または CPickle を使用します (実行パフォーマンスを向上させるため)。Amber が指摘したように、Json 経由でダンプ/ロードすることもできます。人間が判読できるようになりますが、より多くのディスクが必要になります。

于 2012-08-06T00:46:05.400 に答える
0

JSON (または YAML など) のシリアル化の方がおそらく優れていますが、辞書を既に Python 構文でテキスト ファイルに書き込んでいて、変数名のバインドを完了している場合は、代わりにそれを .py ファイルに書き込むことができます。次に、その python ファイルはインポート可能で、そのまま使用できます。そのファイルでグローバルとして直接使用できるため、「辞書を返す関数」アプローチは必要ありません。例えば

# generated.py
please_dont_use_dict_as_a_variable_name = {'Adam': 'Room 430', 'Bob': 'Room 404'}

それよりも:

# manually_copied.py
def get_dict():
    return {'Adam': 'Room 430', 'Bob': 'Room 404'}

唯一の違いは、 [1] が単一の共有オブジェクトであるのmanually_copied.get_dictに対し、辞書の新しいコピーが毎回提供されることです。generated.please_dont_use_dict_as_a_variable_nameこれは、辞書を取得した後にプログラムで辞書を変更する場合に問題になる可能性がありますが、1 つを他の辞書とは別に変更する必要がある場合は、いつでもcopy.copyまたはを使用して新しいコピーを作成できます。copy.deepcopy


[1] dictliststrintmapなどは、一般的に不適切な変数名と見なされます。その理由は、これらがすでに組み込みとして定義されており、非常に一般的に使用されているためです。したがって、そのような名前を付けると、少なくともコードを読んでいる人 (しばらく離れていたあなたを含む) に認知的不協和を引き起こすことになりますdict。ここで通常行うことを意味します。」またdict、コードの一部がtype dictを使用しようとしているのに、辞書オブジェクトを取得しているため、ある時点で、オブジェクトが呼び出し可能ではない (または何か) という、腹立たしい解決すべきバグが報告される可能性が非常に高くなります。dict代わりに名前にバインドされます。

于 2012-08-06T02:53:25.367 に答える
0

JSON 方向には、simpleJSON と呼ばれるものもあります。初めてPythonでjsonを使用したとき、jsonライブラリが機能しませんでした/理解できませんでした。simpleJSON の方が使いやすかった

于 2012-08-06T02:01:49.880 に答える