Python类使用大型查找表

问题描述 投票:1回答:2

在过去的几年里,我一直在修补Python(v3)。作为一个学习练习,几周前我决定重构我写的一系列bash脚本。我还认为该语言的某些功能将大大加快处理速度。这些bash脚本通常运行5或6天来处理大量数据文件。 Python版本还显着提高了代码的可读性和可维护性。

首先,我将算法作为一个程序在一个文件中运行。该算法使用几个大型查找表,以列表和字典的形式实现。现在我想要分解它 - 核心逻辑进入一个文件,第二个文件包含一个包含查找表及其相关函数的类(es?)。数据表大约需要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的内存,再加上在启动时从磁盘读取的额外数据总数大约为600MB。我认为这意味着案例2是我想要的,但我不确定。我来自一个主要使用C的嵌入式背景,所以面向对象的技术不是我的专长 - 然而!

python class module constants lookup-tables
2个回答
1
投票

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

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


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... >>>

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

© www.soinside.com 2019 - 2024. All rights reserved.