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

时间:2017-01-13 12:51:55

标签: python python-2.7 importerror

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

该模型具有以下结构:

Island课程(landscape.py

  • 具有坐标
  • 的景观单元格的集合

Cell课程(landscape.py

  • 所有景观单元格的超类(JungleSavannahMountain等)。细胞类具有该细胞中具有不同动物的字典。
  • animal字典的结构如下:

    animals = {AnimalType1: [animal1_inst_1, animal_2_inst_2],
               AnimalType2: [animal2_inst_1, animal_2_inst_2]}
    
  • 每个单元格的初始animal字典都是在运行时设置的。

Animal课程(animals.py

  • 所有动物类型的超类(目前只有HerbivoreCarnivore)。
  • 所有动物类都有一个类变量allowed_cells,它是这种动物可以驻留的所有细胞类型的列表,例如

    allowed_cells = [landscape.Jungle, landscape.Savannah]
    

我的问题是这样 - 在landscape.py中导入animals.py以检查动物词典中的所有键是否为Animal子类,以及相应列表中的所有实例是否是该动物类的实例。在animals.py中,导入landscape.py,以便allowed_cells列表可以与实际的单元类一起使用,此外还有其他地方的许多测试。

当我尝试运行代码时,我收到错误:

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类创建一个is_animal函数,并使用try / except的一些解决方法,但至少可以说这看起来非常不透明。

最佳解决方法是什么?

2 个答案:

答案 0 :(得分:4)

animals导入landscape以定义动物可以居住的地方似乎很自然。另一方面,我不明白你在Animal中需要landscape的原因。一个单元格可以(可能)存在而不包含任何Animal,但每个Animal必须存在于一个单元格中。因此,您应该尝试从landscape中删除动物内容,此模块应仅包含横向类。实例化应该在不同的模块中进行,并且在实例化时应该用动物填充细胞。因此,将动物列表作为__init__的参数。

请注意,您可以通过子类检查执行is_animal形式的检查。即如果Dog继承自Animal,则issubclass(Dog, Animal)评估为True。您还可以将abstract base classes用于register个其他类作为子类。

答案 1 :(得分:0)

尝试在Animal内导入landscape.py,而不是在文件的开头,但在本地,在函数中导入,检查密钥类。

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