Вопрос

Я анализирую файл с помощью Python и пипарсинг (это файл отчета для PSAT в Matlab, но это не важно). здесь это то, что у меня есть до сих пор.Я думаю, что это беспорядок, и хотел бы получить совет, как его улучшить.В частности, как мне организовать определения грамматики с помощью pyparsing?

Должен ли я объединить все определения грамматики в одну функцию?Если да, то это будет одна огромная функция.Если нет, то как мне его разбить.На данный момент я разбил его на разделы файла.Стоит ли создавать множество функций, которые вызываются из одного места только один раз?Ни то, ни другое мне не кажется правильным.

Должен ли я поместить весь свой входной и выходной код в отдельный файл для других функций класса?Это сделало бы цель класса намного яснее.

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

(Я приму ответы это достаточно хорошо или используйте X вместо pyparsing если люди согласятся)

Это было полезно?

Решение

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

Я вижу, что вы определили несколько полезных вспомогательных утилит, таких как slit («подавить литерал», я полагаю), stringtolits и decimaltable.Мне это кажется хорошим.

Мне нравится, что вы используете имена результатов, они действительно повышают надежность вашего кода после анализа.Я бы рекомендовал использовать форму ярлыка, добавленную в pyparsing 1.4.7, в которой вы можете заменить

busname.setResultsName("bus1")

с

busname("bus1")

Это может немного разгрузить ваш код.

Я бы просмотрел ваши действия по анализу, чтобы увидеть, где вы используете числовые индексы для доступа к отдельным токенам, и вместо этого вернулся бы и назначил имена результатов.Вот один случай, когда GetStats возвращает (ngroup + sgroup).setParseAction(self.process_stats).Process_stats имеет такие ссылки, как:

self.num_load = tokens[0]["loads"]
self.num_generator = tokens[0]["generators"]
self.num_transformer = tokens[0]["transformers"]
self.num_line = tokens[0]["lines"]
self.num_bus = tokens[0]["buses"]
self.power_rate = tokens[1]["rate"]

Мне нравится, что вы сгруппировали значения и статистику, но давайте дадим им имена, например «сеть» и «солн».Затем вы могли бы написать этот код действия синтаксического анализа как (я также преобразовал в более удобную для чтения нотацию атрибута объекта вместо нотации элемента dict):

self.num_load = tokens.network.loads
self.num_generator = tokens.network.generators
self.num_transformer = tokens.network.transformers
self.num_line = tokens.network.lines
self.num_bus = tokens.network.buses
self.power_rate = tokens.soln.rate

И еще вопрос по стилю:почему вы иногда используете явный конструктор And вместо оператора «+»?

busdef = And([busname.setResultsName("bus1"),
            busname.setResultsName("bus2"),
            integer.setResultsName("linenum"),
            decimaltable("pf qf pl ql".split())])

Так же легко пишется:

busdef = (busname("bus1") + busname("bus2") + 
            integer("linenum") + 
            decimaltable("pf qf pl ql".split()))

В целом, я думаю, это примерно нормально для файла такой сложности.У меня есть похожий формат (собственный, к сожалению, поэтому не может быть передан), в котором я собирал код по частям, как у вас, но в один большой метод, примерно так:

def parser():
    header = Group(...)
    inputsummary = Group(...)
    jobstats = Group(...)
    measurements = Group(...)
    return header("hdr") + inputsummary("inputs") + jobstats("stats") + measurements("meas")

Конструкции Group особенно полезны в таких больших анализаторах, как этот, поскольку они позволяют создать своего рода пространство имен для имен результатов в каждом разделе анализируемых данных.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top