Класс Python, использующий большие таблицы поиска - PullRequest
1 голос
/ 17 апреля 2019

Последние несколько лет я работал с Python (v3).В качестве учебного упражнения я решил пару недель назад провести рефакторинг коллекции написанных мной сценариев bash.Я также думаю, что некоторые особенности языка значительно ускорят обработку.Эти сценарии bash обычно выполняются в течение 5 или 6 дней, обрабатывая огромные файлы данных.Версия Python также значительно улучшает удобочитаемость и удобство сопровождения кода.

Сначала я получил алгоритмы, работающие как программа, в одном файле.Алгоритм использует несколько больших справочных таблиц, реализованных по-разному в виде списков и словарей.Теперь я хочу разбить его - основная логика собирается в один файл, а второй файл содержит класс (ы), содержащий таблицы поиска и связанные с ними функции.Таблицы данных занимают около 350 строк кода, а функции имеют примерно одинаковый размер.

В: Каков предпочтительный способ структурирования файла модуля класса?

Например, я начал делать это так, назовем это case 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... >>>

Таблицы данных по существу постоянны.Если когда-либо была причина создать два экземпляра этого класса, данные должны быть общими, а не дублироваться.Статические данные в исходном коде занимают десятки МБ памяти, в сочетании с дополнительными данными, считываемыми с диска при запуске, общая сумма составляет около 600 МБ).Я думаю, это означает, что случай 2 - это то, что я хочу, но я не уверен.Я пришел из встроенного фона, используя в первую очередь C, поэтому объектно-ориентированные методы не моя специальность - пока!

Ответы [ 2 ]

1 голос
/ 17 апреля 2019

Лично я не буду хранить большие списки внутри одного модуля с классом. Как насчет сохранения их в каком-либо формате во внешнем модуле python, который управляет ими и загружает их, когда вам это нужно?

В зависимости от размера и потребностей вы можете использовать pickle, pandas, csv или напрямую базу данных SQL / NoSQL.

0 голосов
/ 19 апреля 2019

Спасибо за предложения, они помогли мне найти работоспособное решение и лучше понять модуль против переменных класса против экземпляра. Я решил поместить все в один класс в модуле.

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

Эта схема, в которой я определяю пустые таблицы вверху и расширяю / обновляю их данными внизу, была необходима для решения проблем с циклическими ссылками. Один из списков - это таблица переходов, ссылающаяся на функции в классе, поэтому я не мог сначала определить таблицы, а также не мог определить функции в первую очередь.

...