5

我正在为我用 python 编写的 boggle-clone 创建一个网络服务器,它接受用户,解决板子,并对玩家输入进行评分。我使用的字典文件是 1.8MB(ENABLE2K 字典),我需要它可用于多个游戏求解器类。现在,我拥有它,以便每个类逐行遍历文件并生成一个哈希表(关联数组),但是我实例化的求解器类越多,占用的内存就越多。

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

4

4 回答 4

11

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

import dictionary

dictionary.words[whatever]

哪里 dictionary.py 有:

words = {}

# read file and add to 'words'
于 2008-10-01T17:30:41.083 回答
1

尽管此时它本质上是一个单例,但通常反对全局变量的论点仍然适用。对于 pythonic 单例替代,查找“borg”对象。

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

于 2008-10-01T16:55:23.103 回答
1

亚当,当你说:

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。

于 2008-10-01T20:00:11.583 回答
0

根据您的 dict 包含的内容,您可能对“搁置”或“anydbm”模块感兴趣。它们为您提供类似 dict 的接口(只是字符串作为“anydbm”的键和项目,字符串作为键和任何 python 对象作为“搁置”的项目)但数据实际上位于 DBM 文件中(gdbm、ndbm、dbhash、 bsddb,取决于平台上可用的内容。)您可能仍希望按照您的要求在类之间共享实际数据库,但它会避免解析文本文件步骤以及保留所有内容-记忆位。

于 2008-10-01T19:38:26.860 回答