如何修改软件架构以解决循环导入?

How to modify software architecture in order to resolve circular import?

我目前正在编写一些用于人口模型模拟的 Python 2.7 代码,我遇到了循环导入的问题。

模型结构如下:

Islandclass(在landscape.py

Cellclass(在landscape.py

Animalclass(在animals.py

我的问题是 - animals.py 导入 landscape.py 以检查动物字典中的所有键是否都是 Animal subclasses 以及是否所有实例都在相应的列表是该动物的实例 class。在 animals.py 中,导入 landscape.py 以便 allowed_cells 列表可以包含实际单元格 classes,此外还有其他地方的许多测试。

当我尝试 运行 代码时,出现错误:

Traceback (most recent call last):
  File "C:/Users/yngve_000/Documents/INF200/inf200_dag_yngve/PA04/biosim/simulation.py", line 10, in <module>
    import landscape as landscape
  File "C:\Users\yngve_000\Documents\INF200\inf200_dag_yngve\PA04\biosim\landscape.py", line 12, in <module>
    import animals
  File "C:\Users\yngve_000\Documents\INF200\inf200_dag_yngve\PA04\biosim\animals.py", line 18, in <module>
    class Animal(object):
  File "C:\Users\yngve_000\Documents\INF200\inf200_dag_yngve\PA04\biosim\animals.py", line 70, in Animal
    allowed_cell_types = [landscape.Jungle, landscape.Desert,
AttributeError: 'module' object has no attribute 'Jungle'

我明白为什么会出现这个错误,但不知道如何以优雅的方式消除它。可以为 Animal class 创建一个 is_animal 函数并使用 try/except 的一些变通方法,但至少可以说这似乎很麻烦。

最好的解决方法是什么?

animals 导入 landscape 以定义动物可以居住的地方似乎很自然。另一方面,我不明白为什么 landscape 中需要 Animals。一个单元格可以(可能)在没有任何 Animal 的情况下存在,但每个 Animal 都必须存在于一个单元格中。所以你应该尝试从 landscape 中删除动物的东西,这个模块应该只包含景观 类。实例化应该发生在不同的模块中,并且单元格应该在实例化时填充动物。因此,使动物列表成为 __init__.

的参数

请注意,您可以通过子类检查执行 is_animal 形式的检查。 IE。如果 Dog 继承自 Animal,则 issubclass(Dog, Animal) 的计算结果为 True。你也可以使用 abstract base classes to register other 类 as sub类.

尝试在 landscape.py 内部导入 Animal,而不是在文件开头,而是在本地,在检查键 类 的函数 中].

实际上,这是一种常见的方法——当你面临循环导入时,使用本地导入。但要小心 — 循环导入通常表明您的代码在耦合方面存在问题。