如何避免循环依赖?

时间:2019-08-14 12:57:14

标签: python python-3.x circular-dependency

我有两个文件,两个文件都定义了一个类。

project/
    __init__.py
    thing.py
    thinglist.py

thing.py定义了一个类Thing,该类可以输出其他Thing的列表:

# thing.py
from project.thinglist import ThingList
class Thing:
    def make_more_things(self):
        return ThingList(Thing(), Thing())

ThingListThing对象的列表,它扩展了列表并添加了一些其他功能:

# thinglist.py
from project.thing import Thing
class ThingList(list):
    def __init__(self, *args):
        list.__init__(self, *args)
        assert all([isinstance(t, Thing) for t in self])
    def some_other_method: pass

立即有一个问题:循环依赖。 Thing需要ThingList才能构建ThingListsThingList需要Thing才能验证它是由Thing组成的。但是Python不允许我将Thing导入thinglist.py

要解决这个问题,我可以将两个类都放在同一个文件中。但是它们都很长,为了我自己的理智,我真的不想这样做。我也可以省略isinstance检查,但是可能会遇到一些错误,这些错误现在可以轻松解决。

如何在不合并两个文件的情况下避免这种循环依赖?

1 个答案:

答案 0 :(得分:1)

如果指定容器数据类型的唯一目的是执行测试,则可以编写具有所有逻辑(附加,类型检查)的类似模板的类Container,并仅以Thing作为容器类型的子类稍后在thing.py中。

例如,在thinglist.py中您将拥有

class Container:

    def __init__(self):
        if not hasattr(self, 'type_ref'):
            raise NotImplementedError("Type should be set in subclass")
        self._data = []

    def append(self, elt):
        if not isinstance(elt, self.type_ref):
            raise TypeError(f'Element should be of type {self.type_ref}')
        self._data.append(elt)

    ... # rest of the logic

thing.py

from thinglist import Container

class ThingList(Container):
    type_ref = Thing