类架构:Python中内外类的循环依赖

乔纳森·舒尔巴赫

我的设计

口头描述

我有一个类Model,当然有一些方法。除此之外,我有一个类,ModelList其子类表示 .q 子类的实例列表Model除其他外,ModelList子类的用途是提供批量操作,这不同于仅将操作委托给ModelList. 因此,ModelList子类的目的是“向量化”相应Model类的方法

我还在ModelList某些地方使用了,我希望允许子类ModelModelList允许作为传递给函数的参数。

ModelList正在了解(并检查)其任何元素将被接受的类型。为了让子类ModelList知道其对应的Model子类,我将定义为子类element_type上的类变量ModelList

每个ModelList子类都与一个子类紧密耦合Model:一个ModelList类属于一个Model类。这就是为什么我将ModelList子类作为其各自Model的内部类。我的问题来了:因为在每个类的初始化过程中ModelList需要知道ModelModel需要知道ModelList两者,所以我的类之间存在循环依赖关系。

最小示例

我将代码简化为最小示例,以使我的设计更易于理解:

class Model(ABC):
    pass
class ModelList(list):
    @classmethod
    def __init__(self, elements=None):
        elements = list() if not elements else elements

        for value in elements:
            self._check_type(value)

        list.__init__(self, elements)

    def _check_type(self, val):
        if not isinstance(val, self.__class__.element_type):
            raise TypeError(
            f"{self.__class__} accepts only instances of {self.__class__.element_type} as elements. `{val}` is not!") 

以下导致错误free variable 'SomeModel' referenced before assignment in enclosing scope

class SomeModel(Model):
    class List(ModelList):
        element_type = SomeModel  # this causes the Error

我不想解耦

我知道我可以通过解耦这两个类来摆脱循环依赖。但我无论是Model类知道其对应的ModelList类,也是我想要的ModelList类以了解它的Model类。每个Model班级都应该有一个并且只有一个List附加到它。

猴子补丁合适吗?

我知道我可以通过Model像这样“monkeypatching”我的子类来规避依赖

class SomeModel(Model):
    pass

class SomeModelList(ModelList):
        element_type = SomeModel

SomeModel.List = SomeModelList

对我来说,感觉这是设计缺陷的标志。我说不出为什么,但感觉“错了”。

问题

  1. 猴子补丁在这里合适吗?或者它是否表明我的设计存在更深层次的概念问题?
  2. 还有哪些其他解决方案?
  3. 如何重新设计以摆脱这种循环依赖(但仍保持类的耦合)?
  4. 是否可以element_type在稍后Model定义相应的子类评估
阿兰·T。

如果你想让 SomeModelList 表现得像一个泛型,你应该提供元素类作为构造函数的参数并将它分配给 self.element_type 那里。

class ModelList(list):

    def __init__(self, model, elements=None):
        self.element_Type = model 
        elements = list() if not elements else elements

        for value in elements:
            self._check_type(value)

        list.__init__(self, elements)

    def _check_type(self, val):
        if not isinstance(val, self.element_type):
            raise TypeError(
            f"{self.__class__} accepts only instances of {self.element_type} as elements. `{val}` is not!") 


# usage

modelList = ModelList(SomeModel,[instance1,instance2,instance3])

然后,您可以通过向 Model 基类添加一个类方法来概括这一点(假设您在 Model 之前定义了 ModelList):

class Model:

    ... your other methods ...

    @classmethod
    def List(self,elements=None):
        return ModelList(self.__class__,elements)

# usage

class SomeModel(Model): pass

modelList = SomeModel.List([instance1,instance2,instance3]) 

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

python类之间的循环依赖

来自分类Dev

C ++类中的循环依赖

来自分类Dev

循环依赖类中的Typedef

来自分类Dev

模板类中的循环依赖

来自分类Dev

C ++类中的循环依赖

来自分类Dev

类构造函数中的循环依赖

来自分类Dev

Rails:关联的STI类中的循环依赖

来自分类Dev

类构造函数中的循环依赖

来自分类Dev

修复算术类中的循环依赖

来自分类Dev

设计:类循环依赖吗?

来自分类Dev

C ++类之间的循环依赖

来自分类Dev

使用引用的 C++ 类中的循环依赖项

来自分类Dev

类中的数据依赖

来自分类Dev

类中的Python类

来自分类Dev

模板类成员函数之间的循环依赖

来自分类Dev

Python类变量依赖项

来自分类Dev

.XSD文件架构中的JAXB类

来自分类Dev

Python从类中引用类

来自分类Dev

如何在iOS iPhone应用程序中对循环依赖项使用正向类声明?

来自分类Dev

引用窗口表单应用程序和类库中的循环依赖问题

来自分类Dev

定义新类时在__init__内外引发Python异常

来自分类Dev

将依赖项注入Facade类中包含的类中

来自分类Dev

使用while循环来迭代python 3中的类成员

来自分类Dev

如何使用For循环打印python类中的所有项目

来自分类Dev

如何从原始类文件中找出依赖类?

来自分类Dev

在Startup类中获取依赖于DI的类的实例

来自分类Dev

窗口小部件依赖类Python TKinter

来自分类Dev

Python:定义具有依赖属性的类

来自分类Dev

Python 类的相互依赖关系