Closed fizmat closed 6 years ago
Я люблю повторяться поменьше и питон позволяет сильно всё сокращать, но есть опасность, что я из-за этого заворачиваю нечитаемые конструкции. Главная цель переделки конфига в виде двух "слоёв" классов - оставить совместимый с проектом ef набор классов - секций конфига, но при этом иметь возможность менять структуру внутреннего представления конфига на более удобную, которую можно например и рисовать.
В-общем, я начал смотреть код, но не успел за "несколько дней или в крайнем случае неделю", как обещался. Потом выпал примерно на месяц из деятельности по этой программе. Нехорошо получилось.
Думаю, чтобы такого больше не повторялось - чтобы готовая функциональность не висела месяц без дела - наверное, будет лучше вносить изменения без моего подтверждения. А потом я уже буду разбираться, что и как работает.
Ладно. Как я понял, ситуация следующая:
Есть два параллельных набора классов: одни наследуются от ConfigComponent
, вторые - от ConfigSection
. Например, class TimeGrid(ConfigComponent)
и class TimeGridConf(ConfigSection)
.
"Компоненты" (те, что наследуются от ConfigComponent
) что-то знают про свое содержимое.
В частности, умеют его визуализировать. Данные хранятся в удобном для этого формате.
Собственно, единственный метод в ConfigComponent
это visualize
.
Предполагается, что в наследуемых классах он будет переопределяться по мере надобности.
class ConfigComponent(DataClass):
def visualize(self, visualizer):
pass
"Секции" (те, что наследуются от ConfigSection
) нужны для конвертации данных между форматом конфига расчетной программы и форматом в компонентах. Они общаются в-основном с питоновским Config Parser'ом: импорт с помощью конструктора from_section(cls, section)
и экспорт с помощью add_section_to_parser(self, conf)
.
Для секций с именами (типа ParticleSourceBox.cathode
) есть NamedConfigSection
.
Декоратор @register
добавляет соответствие между названием секции в конфиге расчетной программы и классом, унаследованным от ConfigSection
. Добавляет в словать section_map
в классе ConfigSection
. Поскольку этот класс родительский для всех секций, section_map
оказывается общей для всех классов-потомков. Кстатии, почему register
определен два раза? Один раз как classmethod
в ConfigSection
и один раз глобально?
В каждом Section-классе определен метод make
, который позволяет собрать объект класса Component из этого Section-объекта.
Каждый section-класс, который можно отобразить в component-класс, определяется в фаиле component-класса. Например, @register \n class InnerRegionBoxConf(NamedConfigSection)
определен в components/inner_region.py
вместе с компонентом InnerRegion(ConfigComponent)
. Поля конфига расчетной программы вписываюстя в ContentTuple
как именованный кортеж. Данными из ContentTuple
инициализируется self.content
, который потом используется для экспорта в конфиг расчетной программы в add_section_to_parser
.
Т.е. в итоге если мне нужно добавить новую секцию в конфиг расчетной программы, то мне нужно
1) определить component-класс, который будет его визуализировать.
2) зарегистрировать section-класс, который будет отвечать за конвертацию между component-классом и конфигом расчетной программы. За импорт из конфига программы в component отвечает метод make
section-класса, за экспорт из component-класса в section отвечает метод to_conf
component-класса.
Классы ConfigComponent
, ConfigSection
и EfConf
наследуются от DataClass
, чтобы не переопределять каждый раз встроенные методы: __repr__
, __hash__
и __eq__
.
Где-нибудь в коде эти методы явно используются? Или это просто правила приличия?
Еще геометрические формы источников и внутренних областей обобщены (и унаследованы от Shape()
). Есть визуализатор этих объектов, в написание которого тоже было вложено много усилий. Умеет как wireframe, так и solid. Знает про потенциалы. Использует только matplotlib. Есть наклон для оси цилиндра.
В-общем, очень круто.
Привет!
Посмотрел код. Все, конечно, сделано гораздо круче, чем обычно пишу я. Здорово, что работают примеры и визуализация всех полей конфига. Даже потенциалы. Процедура расчетов наконец-то сильно упростится!
Я пока не разобрался в деталях, как все реализовано. Но хотел бы составить себе хотя бы высокоуровневое впечатление. Думаю, что в течение нескольких дней, в крайнем случае недели, я это сделаю.
Я попробую сформулировать здесь свое понимание и какие-то вопросы (если будут). Потом можно будет залить код в master-ветку.
Хотя можно, конечно, уже и сейчас залить...