使用大型查找表的Python类

时间:2019-04-17 12:18:57

标签: python class module constants lookup-tables

在过去的几年中,我一直在反复研究Python(v3)。作为一项学习练习,我几周前决定重构我编写的bash脚本集合。我还认为该语言的某些功能将大大加快处理速度。这些bash脚本通常运行5或6天,以处理巨大的数据文件。 Python版本还大大提高了代码的可读性和可维护性。

首先,我将算法作为一个程序工作在一个文件中。该算法使用几个大型查找表,分别以列表和字典的形式实现。现在,我想对其进行分解-核心逻辑进入一个文件,而第二个文件包含一个包含查找表及其相关函数的类。数据表大约需要350行代码,而函数的大小大约相同。

问:构造类模块文件的首选方法是什么?

例如,我开始以这种方式进行操作,我们称之为案例1:

class Zebra:
    _stripe_keys = [ ....... ]
    _stripe_info = [ [.....], [.....], ... [.....] ]
    _stripes = [ dict(zip( stripe_keys, info )) for info in stripe_info ]
    <<< many such tables >>>
    def __init__(self, name):
        self.name = name
    def function_one(self):
        do something
    def function_two(self):
        do something
    <<< etc... >>>

然后我意识到情况2可能会更好:

_stripe_keys = [ ....... ]
_stripe_info = [ [.....], [.....], ... [.....] ]
_stripes = [ dict(zip( stripe_keys, info )) for info in stripe_info ]
<<< many such tables >>>
class Zebra:
    def __init__(self, name):
        self.name = name
    def function_one(self):
        do something
    def function_two(self):
        do something
    <<< etc... >>>

然后我看到了情况3的另一种可能性,但是我不得不以某种方式将数据类传递给函数类:

class ZebraTables:
    _stripe_keys = [ ....... ]
    _stripe_info = [ [.....], [.....], ... [.....] ]
    _stripes = [ dict(zip( stripe_keys, info )) for info in stripe_info ]
    <<< many such tables >>>
    def __init__(self, name):
        self.name = name
class Zebra:
    def __init__(self, name):
        self.name = name
    def function_one(self):
        do something
    def function_two(self):
        do something
    <<< etc... >>>

数据表本质上是恒定的。如果有理由创建该类的两个实例,则数据应该共享而不是重复。源代码中的静态数据占用数十MB的内存,再加上启动时从磁盘读取的其他数据,总计约600 MB。我认为这意味着情况2是我想要的,但我不确定。我来自主要使用C的嵌入式背景,所以面向对象技术不是我的专长-

2 个答案:

答案 0 :(得分:1)

就我个人而言,我不会将大型列表存储在与该类相同的模块中。如何将它们以某种格式保存在外部python模块中,该模块可以管理它们并在需要时加载它们?

根据大小和需求,您可以使用picklepandascsv或直接使用SQL / NoSQL DB。

答案 1 :(得分:0)

感谢您的建议,他们帮助我找到了可行的解决方案,并更好地理解了模块,类和实例变量。我决定将所有内容都放在该模块的一个类中。

class Zebra:
    stripe_keys = []
    stripe_info = []
    stripes = defautdict(list)
    <<< many such tables >>>
    def __init__(self, name):
        self.name = name
        self.init_stripes()
    def function_one(self):
        do something
    def function_two(self):
        do something
    def init_stripes(self):
        Zebra.stripe_keys.extend([.........])
        Zebra.stripe_info.extend([ [...], [...], ..., [...] ])
        Zebra.stripes.extend([ dict(zip( Zebra.stripe_keys, info )) 
                               for info in Zebra.stripe_info ])
    <<< etc... >>>

这种安排(我在顶部定义空表并在底部使用数据扩展/更新它们)对于解决循环引用问题是必需的。列表之一是类中引用函数的跳转表,因此我无法首先定义表,也无法首先定义函数。