Python3:如何重新设计嵌套类层次结构以更好地序列化和/或促进更好的模型/视图解耦

2024-10-04 03:17:52 发布

您现在位置:Python中文网/ 问答频道 /正文

我和我的一个朋友,我们一直在为光学光线跟踪器开发代码。这种光学光线跟踪器由对象层次结构组成,其中某些类包含变量,这些变量被实现为或多或少复杂的有状态对象。这些类还可以包含其他类似类的实例,这些类还包含这些变量对象或其他类实例。你知道吗

首先,我们将提供一个“最小”的工作示例:

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被收集起来,它们的状态被用来将它们放入一个numpy数组中,并将它们交给优化器。你知道吗

对象(A、B、C)可以以递归方式连接,因此序列化和对OptVar对象的轻松访问相当复杂。对于a)部分,代码中没有解决方案。b)部分目前的解决方案是遍历对象层次结构,从my\u a\u obj到b\u obj,再到c\u obj,收集所有OptVar对象(通过使用id列表防止加倍)并返回dict。这是可行的,但对我们来说,这只是一个临时解决方案,非常难看。你知道吗

总体目标是通过使用dict来传递数据,使序列化和以后与GUI的交互变得非常容易。(有没有更好的方法来解决这两项任务?)这也将简化optvarcontainer和Optimizer之间的交互,因为接口只是dict。你知道吗

我们对a)做了一些研究,找到了pickle、JSON和YAML用于序列化。我们还用jsonpickle做了一些测试,它的工作不会遇到递归对象层次结构的问题。既然jsonpickle自动完成了所有的序列化,我们就不必关心这一点。对我们来说,主要的缺点是,如果基础对象发生更改,jsonpickle的对象将无法重建,因此没有版本稳定性。此外,编写序列化程序后端而不淹没在管理代码中似乎相当复杂。因此,我们的决定是在一天结束时有一个非常简单的YAML“dictionary”,类层次结构中的每个对象都应该根据请求提供自己的dict(在理想世界中,这个dict也可以用来重构对象)。这里的问题是:如何在一个相当普遍的方式实现这一点?纪念品设计模式是否适用于此?它能用在上面给出的A,B,C上下文中吗?这些类只是相似的,不相等的,并且以这种复杂的方式相互连接?你知道吗

我们还对b)做了一些思考,我们认为某种类型的optvar池会很好,因为这个池很容易被遍历,并且可以包含复杂的有状态变量对象。在类A,B,C中,我们只提供一些到OptVars的“链接”。然而,这种方法有两个主要问题:

  • 如何实现这样一个对象池?我读到过一个设计模式,它是作为一个单例实现的,但是在我们的例子中,单例可能不是最好的选择。这是因为一次应该有多个池(可能针对不同版本的类层次结构,或者加载和保存池)。它也不只是一个数据接收器,也没有一个全局状态。你知道吗
  • 如何管理这样的池以及如何将其实现到Python中?我们不希望有一个全局变量,但也不希望每次创建a、B、C对象时都提供这个池。有没有更好的可能性把OptVa自动进入一个给定的池?你知道吗
  • pool OptVars和A、B、C OptVars之间的链接应该如何实现?代理设计模式?还有其他的设计模式吗?你知道吗

如果问题不适合stackexchange或格式比较混乱,我很抱歉。我知道,这是没有问题的具体和独特的解决方案存在,但对我们来说,这是必须得到一些投入。你知道吗


Tags: 对象selfobj序列化层次结构initmydef