Pythonで大きなテキストファイルを保存して使用する最良の方法
質問
私は、ユーザーを受け入れ、ボードを解決し、プレイヤーの入力をスコアリングするpythonで作成したboggle-cloneのネットワークサーバーを作成しています。私が使用している辞書ファイルは1.8MB(ENABLE2K辞書)であり、いくつかのゲームソルバークラスで使用できるようにする必要があります。現在、各クラスがファイルを1行ずつ反復してハッシュテーブル(連想配列)を生成するようにしていますが、インスタンス化するソルバークラスが多いほど、より多くのメモリを消費します。
辞書ファイルを一度インポートして、必要に応じて各ソルバーインスタンスに渡します。しかし、これを行う最良の方法は何ですか?辞書をグローバルスペースにインポートし、ソルバークラスでglobals()['dictionary']としてアクセスする必要がありますか?または、辞書をインポートしてから、クラスコンストラクターに引数として渡す必要がありますか?これらの1つは他よりも優れていますか? 3番目のオプションはありますか?
解決
ファイルを読み込んで辞書を作成するコードを含むdictionary.pyモジュールを作成する場合、このコードは最初にインポートされたときにのみ実行されます。さらにインポートすると、既存のモジュールインスタンスへの参照が返されます。そのため、クラスでは次のことができます。
import dictionary
dictionary.words[whatever]
dictionary.pyの場所:
words = {}
# read file and add to 'words'
他のヒント
この時点では本質的にシングルトンですが、グローバルに対する通常の引数が適用されます。 pythonic singleton-substituteの場合は、「borg」を検索します。オブジェクト。
それが本当に唯一の違いです。ディクショナリオブジェクトが作成されると、ディープコピーを明示的に実行しない限り、それを渡すときに新しい参照のみをバインドします。各ソルバーインスタンスが変更のためにプライベートコピーを必要としない限り、1回だけ集中的に構築されることは理にかなっています。
アダム、Pythonで次のように言うことを思い出してください:
a = read_dict_from_file()
b = a
...実際にはコピー a
ではないため、より多くのメモリを使用するため、同じものへの別の参照を b
するだけです。オブジェクト。
つまり、基本的に、提案するソリューションの任意のは、メモリ使用量の点ではるかに優れています。基本的には、辞書を 1回読んでから、それへの参照につかまってください。グローバル変数を使用して実行する場合でも、各インスタンスに渡す場合でも、他の何かに渡す場合でも、同じオブジェクトを参照し、それを複製することはありません。
最もPythonicなのはどれですか?それは完全に「ワームのもう一つの缶」ですが、私が個人的にすることは次のとおりです:
def main(args):
run_initialization_stuff()
dictionary = read_dictionary_from_file()
solvers = [ Solver(class=x, dictionary=dictionary) for x in len(number_of_solvers) ]
HTH。
dictの内容によっては、 'shelve'または 'anydbm'モジュールに興味があるかもしれません。彼らはあなたにdictのようなインターフェース( 'anydbm'のキーとアイテムとしての文字列、および 'shelve'のアイテムとしてのキーと文字列としてのPythonオブジェクト)を提供しますが、データは実際にはDBMファイル(gdbm、ndbm、dbhash、プラットフォームで利用可能なものに応じてbsddb。)おそらく、実際のデータベースをクラス間で共有したいと思うかもしれませんが、テキストファイルの解析ステップとキープ・イット・オール・インを回避します。 -メモリビット。