设计缺陷 - 试图防止交叉进口

时间:2014-01-08 17:24:37

标签: python import

我面临的实际问题比这复杂得多,但这几乎归结为:

World.py

import Cell

worldobjects = []

for i in range(10): #create  a bunch of initial cells
    worldobjects.append(Cell.Cell())

while True:
    for obj in worldobjects:
        obj.update()

Cell.py

from World import worldobjects #This is the problem, python does not like cross imports

class Cell:
    def __init__(self):
        self.lifetime = 0 #Keep track of frames spent 'alive'

    def update(self):
        self.lifetime += 1 
        if self.lifetime > 30:
            worldobjects.append(Cell()) #Add a new cell to the world
            self.lifetime = 0 #Reset lifetime 

该错误有点非特定,但我知道这意味着我不应该交叉导入东西:

ImportError: No module named worldobjects

我知道这是一个设计缺陷,但我不太确定如何以不同的方式解决这个问题。从代码中可以看出,每个单元应该每30帧“重现”一次,唯一可行的方法是将它们添加到World.py文件中的数组中。我考虑过将worldobjects数组移动到自己的文件中,但这对我来说感觉有点脏。有谁可以帮我解决这个问题?

3 个答案:

答案 0 :(得分:2)

如何在您的单元格中保持与worldobjects的链接:

Cell.py

#from World import worldobjects #This is the problem, python does not like cross imports

class Cell:
    def __init__(self, worldobjects):
        self.lifetime = 0 #Keep track of frames spent 'alive'
        self.worldobjects = worldobjects

    def update(self):
        self.lifetime += 1 
        if self.lifetime > 30:
            self.worldobjects.append(Cell(self.worldobjects)) #Add a new cell to the world
            self.lifetime = 0 #Reset lifetime 

World.py

import Cell

worldobjects = []

for i in range(10): #create  a bunch of initial cells
    worldobjects.append(Cell.Cell(worldobjects))

while True:
    for obj in worldobjects:
        obj.update()

答案 1 :(得分:1)

这是全局变量为什么不好主意的一个很好的例子。而不是Cell需要知道全局调用的worldobjects的存在,最好在每个单元创建时告诉每个单元。例如,您可以在构造函数中传递对它的引用。或者创建一个新函数,封装新单元格的创建并告诉它世界对象。

或者,您可以将生命周期检查逻辑完全移出单元格,并将其置于世界更新中。这实际上对我来说更有意义,因为我不会让每个单元负责创建新单元格。

答案 2 :(得分:0)

虽然我同意@RickyA关于此问题以及关于所提供示例设计的所有其他评论,但我遇到了类似Flask和WSGI容器的问题,这些容器需要全局(至少是app对象),所以关于循环的额外警报需要进口。它不是来自外太空,但却是一种麻烦。

也许以下方法可以帮助有类似问题的人(包括这里的海报)。因此,一种可能性是在单独的文件中提取全局变量,该文件用作导入中介。它无法解决循环导入类中的所有问题,但在适用的情况下非常简单。

Cell.py

import WorldObjects

class Cell:
    def __init__(self):
        self.lifetime = 0 #Keep track of frames spent 'alive'

    def update(self):

        self.lifetime += 1 
        if self.lifetime > 30:
            WorldObjects.objects.append(Cell()) #Add a new cell to the world
            self.lifetime = 0 #Reset lifetime

World.py

import Cell
import WorldObjects

for i in range(10): #create  a bunch of initial cells
    WorldObjects.objects.append(Cell.Cell())

while True:
    for obj in WorldObjects.objects:
        obj.update()

WorldObjects.py

objects = []