2008-10-01 26 views
4

我正在为python编写的boggle-clone创建一个网络服务器,它接受用户,解决棋盘问题并对玩家输入进行评分。我使用的字典文件是1.8MB(ENABLE2K字典),我需要它可用于几个游戏解算器类。现在我拥有它,每个类逐行遍历文件并生成一个哈希表(关联数组),但是我实例化的解算器类越多,占用的内存就越多。在Python中存储和使用大型文本文件的最佳方式

我想要做的是导入字典文件一次,并将其传递给每个求解器实例,因为他们需要它。但是,这样做的最好方法是什么?我应该在全局空间中导入字典,然后在解析器类中以globals()['dictionary']的形式访问它?或者我应该导入字典,然后将其作为参数传递给类构造函数?其中一个比另一个好吗?有第三种选择吗?

回答

10

如果您创建了一个dictionary.py模块,其中包含读取该文件并生成字典的代码,该代码仅在第一次导入时执行。其他导入将返回对现有模块实例的引用。因此,您的类可以:

import dictionary 

dictionary.words[whatever] 

其中dictionary.py有:

words = {} 

# read file and add to 'words' 
+0

+1:确实。模块就像Python中的单例对象。 – martineau 2012-11-10 18:10:19

1

尽管它在本质上是一个单身人士,但通常针对全局变量的论点也适用。对于pythonic单态替代品,请查看“borg”对象。

这真的是唯一的区别。一旦创建了字典对象,除非您明确执行深层复制,否则在传递它时只会绑定新的引用。有意义的是,只要每个求解器实例不需要专用副本进行修改,它就一次且只能被集中构建一次。

0

根据你的字典包含,你可能有兴趣在“货架”或“anydbm”模块。它们给你类似字典的接口(只是字符串作为'anydbm'的键和项目,字符串作为键,任何python对象作为'shelve'的项目),但数据实际上是DBM文件(gdbm,ndbm,dbhash, bsddb,这取决于平台上可用的内容。)您可能仍然希望按照您的要求在各个类之间共享实际的数据库,但它可以避免解析文本文件的步骤以及保持全部内容 - 内存位。

1

亚当,请记住,在Python时,你说:

a = read_dict_from_file() 
b = a 

...你是不是真正复制a,从而利用更多的内存,你只是做b另一个引用同一个对象。

所以基本上你提出的解决方案的任何将在内存使用方面会好得多。基本上,阅读字典一次,然后挂在一个参考。无论您是使用全局变量还是将其传递给每个实例或其他东西,您都会引用同一个对象,而不是重复它。

哪一个是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。

相关问题