Python class 使用大型查找表

Python class using large lookup tables

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

首先,我将算法作为一个程序在一个文件中运行。该算法使用几个大型查找表,以列表和字典的形式实现。现在我想把它分解——核心逻辑进入一个文件,第二个文件包含一个 class(es?) 保存查找表及其相关函数。数据表大约需要 350 行代码,函数的大小也差不多。

问:构建 class 模块文件的首选方式是什么?

比如我是这样开始的,姑且称之为案例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 传递到函数 class:

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

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

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

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

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

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

我在顶部定义空 table 并在底部定义 extend/update 数据的这种安排对于解决循环引用问题是必要的。其中一个列表是class中的跳转table引用函数,所以我不能先定义table,也不能先定义函数。