高效存储重复呼叫

时间:2015-08-20 13:23:18

标签: python

以下是一个场景:

  1. 我从数据库(MySQL)中获得了句子列表。
  2. 我将文件读入字典。
  3. 根据字典处理每个句子。
  4. 我最初的(可怕的)方法是:

    1. 有两个模块。
    2. ModuleA从数据库中获取句子,并在每个句子中调用functionB
    3. 位于FunctionB
    4. ModuleB从文件中填充字典。每一次。然后它处理句子。
    5. 这样做是因为我最初分别测试了ModuleB。后来,当FunctionB被反复调用时,我不得不解决这个问题。我的解决方案是将字典的数量从文件移动到单独的函数并设置全局字典。代码如下:

      ModuleA

      import ModuleB
      def main():
          sentences = getSentencesFromDB()
          for (sentence in sentences):
              functionB(sentence)
      

      ModuleB

      dictionary = makeDictionaryFromFile()
      
      def functionB(sentence):
          for word in sentence.split():
              #process sentence using dictionary
      

      现在我的问题是:

      1. 这是解决我问题的正确方法吗?也就是说,这确保文件只读一次吗?
      2. 有没有更好的方法(可能没有使用全局)。
      3. dictionary何时填充?第一次打电话给functionB?或者在导入ModuleB

3 个答案:

答案 0 :(得分:2)

这是一个很好的解决方案;你肯定不想多次读取文件(假设你不希望文件的内容在中途改变)。

您可以将其称为_dictionary,以表明它是其他人无法访问的私人字段。

或者你可以使用memoizing @decorator来隐藏调用者的这种行为,或者像chthonicdaemon建议的那样将_dictionarymakeDictionaryFromFile()包装在一个类中。

但是对于一次性这两个选项都是矫枉过正的,只需将文件读入一个字段并使用它。

答案 1 :(得分:2)

按顺序解决您的问题。

  1. 这肯定是 正确答案。该文件只读一次。可能还有其他正确答案。对于像这样的小程序,您的解决方案就足够了。

  2. 为了工作,dictionary变量需要将其值从一次调用持续到functionB到下一次,这排除了dictionary local < / em>到那个功能。作为替代方案,你可以像@ dimo414建议并使用memoizing decorator那样,或者你可以定义一个类,并使字典成为该类对象的属性(如@cthonicdaemon建议的那样)。另一种方法是将字典文件读入数据库表,然后在functionB中查询数据库中所需的单词。对于非常大的字典,这可能会以速度为代价提高内存效率。老实说,鉴于你的程序的大小,所有这些选项似乎有点矫枉过正。我建议重构其中一个,当它变得更清楚哪一个更有意义,如果那个时候到来的话。另请注意,这些都不是互斥的。如果你愿意,你可以将这三者结合起来。

  3. 在导入模块时,将填充字典作为模块中的顶级变量。

答案 2 :(得分:2)

(1)您现在的方式确保文件只读一次。但是,如果不执行ModuleB中的所有其他代码,在同一次执行ModuleA期间重新读取文件会更加棘手

(2)我会考虑使用一个像这样的对象

class Parser(object):

    def __init__(self, filename='whatever the default filename is'):
        self.dictionary = makeDictionaryFromFile(filename)

    def functionB(self, sentence):
        for word in sentence.split():
            # process sentence using self.dictionary


def main():
    sentences = getSentencesFromDB()
    parser = Parser()
    for (sentence in sentences):
        parser.functionB(sentence)

(3)在您的方法中,导入dictionary时会填充ModuleB