我不确定标题是否清楚(我在这里有点新),所以让我详细说明......想象一下,我有以下简单的项目结构:
test/
|-- __init__.py
|-- windows.py
|-- elements.py
|-- test.py
windows.py
如下:
from elements import Container
class WindowTypes:
TYPE_1 = 1
TYPE_2 = 2
class Window:
def __init__(self):
self.container1 = Container(WindowTypes.TYPE_1)
另一方面,elements.py
:
from windows import WindowTypes
class Container:
def __init__(self, win_type):
if win_type is WindowTypes.TYPE_1:
print('Loading stuff specific for windows of type 1')
else:
print('Doing something else')
如果在test.py
中我创建了一个Window类的实例:
from windows import Window
Window()
我知道我会遇到循环导入错误。但是我需要一个描述性变量来描述我可以从Window
类创建的对象类型。如何在Python中处理这种情况?
PD:对于这种情况,我可以创建另一个文件来保存类型,但是我的项目比代表的要大得多,它仍然很好吗?
答案 0 :(得分:1)
我可以通过两种方式来解决这个问题:
只需导入模块本身,而不是从from ... import ...
的模块导入特定名称。例如,在windows.py
中,而不是写
from elements import Container
写一下
import elements
然后当您想要创建Container
时,请执行以下操作:
self.container1 = elements.Container(WindowTypes.TYPE_1)
这种方法的优点是,在导入模块时,实际上并不强制elements
模块在其中包含名为Container
的任何内容,这样就可以解决循环导入问题问题
我不会太深入了解其工作原理的细节(除非您感兴趣,我可以编辑),但要点是导入过程的第一步涉及将模块标记为已导入,这样任何引用同一模块的import
语句都不会导致重新加载文件。因此,如果您导入A
导入B
再次导入A
,第二次遇到import A
,它就不会执行任何操作并且不会继续循环。您可以利用这一点来允许在许多情况下循环导入的内容,尽管有时它不起作用。
或者您可以将窗口类型移动到单独的模块中。类型枚举可以独立于Window
类而存在,并且将它完全分开并不是一个坏主意,因此想要使用类型的代码不必引入完整的{{1模块。我明白为什么你想把这些类型与windows
实现一起保存,因为这个类型并没有真正用于其他任何东西,但是我认为它不是那么必要,它应该阻止你移动它枚举到单独的模块。 Windows的实现肯定可以跨越几个模块。如果你愿意,你甚至可以把它作为一个子包,即具有像
Window
(根据您的需要进行调整)。