Python3: Как перестроить вложенную иерархию классов для лучшей сериализации и / или облегчения лучшего разделения модели / представления - PullRequest
0 голосов
/ 13 октября 2018

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

Прежде всего, мы приведем «минимальный» рабочий пример:

class OptVar:
    """
    Complicated stateful variable
    """
    def __init__(self, **kwargs):
        self.parameters = kwargs


class OptVarContainer:
    """
    Class which contains several OptVar objects and nested OptVarContainer
    classes. Is responsible for OptVar management of its sub-OptVarContainers
    with their respective OptVar objects.
    """
    def __init__(self, **kwargs):
        for (key, value_dict) in kwargs.items():
            setattr(self, key, OptVar(**value_dict))


class C(OptVarContainer):
    """
    Specific implementation of class OptVarContainer
    """
    def __init__(self):
        super(C, self).__init__(
                **{"my_c_a": {"c1": 1, "c2": 2},
                   "my_c_b": {"c3": 3, "c4": 4}})


class B(OptVarContainer):
    """
    Specific implementation of class OptVarContainer
    """
    def __init__(self):
        super(B, self).__init__(**{"b": {"1": 1, "2": 2}})
        self.c_obj = C()


class A(OptVarContainer):
    """
    Specific implementation of class OptVarContainer
    """
    def __init__(self):
        super(A, self).__init__(
                **{"a1": {"1": 1, "2": 2},
                   "a2": {"a": "a", "b": "b"}})
        self.b_obj = B()


def main():
    # creating OptVarContainer with some nested OptVarContainers.
    my_a_obj = A()
    # It is intended behaviour to access the OptVar objects via
    # scoping within the class hierarchy.
    print(my_a_obj.b_obj.b.parameters)
    my_a_obj.b_obj.b.parameters["2"] = 3
    print(my_a_obj.b_obj.b.parameters)
    print(my_a_obj.b_obj.c_obj.my_c_a.parameters["c1"])
    my_a_obj.b_obj.c_obj.my_c_a.parameters["c1"] = 6
    print(my_a_obj.b_obj.c_obj.my_c_a.parameters)
    # Two major problems:
    # a) Serialization (with compatibility between different versions)
    # b) Access to all OptVar objects at once


if __name__ == "__main__":
    main()

в конце дня оптическая система, которая должна быть оптимизирована (позже), имеет тип OptVarContainer и содержит несколько объектов в иерархическом порядке.

Существуют две основные проблемы:

  • Сериализация объектов без слишком больших усилий по управлению и стабильности версии для взаимодействия с пользовательским интерфейсом или последующей реконструкции
  • Простой доступ к объектам переменных и управление ими, которые каким-то образом распределены в иерархии объектов (для последующей интеграции впользовательский интерфейс)

Для дальнейшей оптимизации собирают OptVars и используют их состояние, чтобы поместить их в пустой массив и передать их оптимизатору.

Объекты (A,B, C) могут быть связаны рекурсивным способом и поэтомуСериализация и легкий доступ к объектам OptVar довольно сложны.Для части а) в коде нет решения.Решение для части b) в данный момент состоит в том, чтобы пройти через иерархию объектов от my_a_obj до b_obj через c_obj, собирая все объекты OptVar (предотвращая дублирование с помощью списка идентификаторов) и возвращая dict.Это работает, но для нас это только временное решение, и оно довольно уродливо.

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

Мы провели некоторое исследование для a) и нашли pickle, JSON, YAML длясериализации.Мы также провели несколько тестов с jsonpickle, который работает без проблем с иерархией рекурсивных объектов.Поскольку jsonpickle выполняет всю сериализацию автоматически, нам не нужно об этом заботиться.Для нас главным недостатком является то, что jsonpickle'd объекты не могут быть восстановлены, если базовые объекты изменяются, поэтому нет стабильности версии.Кроме того, кажется довольно сложным написать бэкэнд сериализатора без утопления в коде управления.Таким образом, наше решение состоит в том, чтобы иметь достаточно простой YAML-словарь в конце дня, и каждый объект в иерархии классов должен предоставлять свой собственный dict по запросу (в идеальном мире этот dict также можно использовать для восстановления объекта).Вопрос в следующем: как добиться этого в целом?Подходит ли для этого шаблон дизайна сувенира?Может ли оно быть использовано в контексте A, B, C, приведенном выше, где классы только похожи, а не равны и взаимосвязаны таким сложным образом?

Мы также немного подумали о b), и мы подумали, что какой-тоПул OptVars было бы хорошо, так как пул легко пересекается и может содержать сложные переменные объекты с состоянием.В классах A, B, C мы тогда предоставили бы только некоторые «ссылки» на OptVars.Тем не менее, у этого подхода есть две основные проблемы:

  • Как реализовать такой пул объектов?Я читал о шаблоне проектирования для этого, который реализован как синглтон, но в нашем случае синглтон, возможно, не самый лучший.Это связано с тем, что одновременно должно быть несколько пулов (возможно, для разных версий иерархии классов или для загрузки и сохранения пулов).Это также не только приемник данных, и он не имеет единого глобального статуса.
  • Как управлять таким пулом и как внедрить его в Python?Мы не хотим иметь глобальную переменную, но мы также не хотим предоставлять пул каждый раз, когда создается объект A, B, C.Есть ли лучшие возможности для автоматического добавления OptVars в данный пул?
  • Как должна быть реализована связь между OptVars и A, B, C OptVars?Прокси дизайн шаблона?Любые другие шаблоны дизайна?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...