在Python

时间:2017-12-30 00:22:58

标签: python

我不确定标题是否清楚(我在这里有点新),所以让我详细说明......想象一下,我有以下简单的项目结构:

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:对于这种情况,我可以创建另一个文件来保存类型,但是我的项目比代表的要大得多,它仍然很好吗?

1 个答案:

答案 0 :(得分:1)

我可以通过两种方式来解决这个问题:

  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,它就不会执行任何操作并且不会继续循环。您可以利用这一点来允许在许多情况下循环导入的内容,尽管有时它不起作用。

  2. 或者您可以将窗口类型移动到单独的模块中。类型枚举可以独立于Window类而存在,并且将它完全分开并不是一个坏主意,因此想要使用类型的代码不必引入完整的{{1模块。我明白为什么你想把这些类型与windows实现一起保存,因为这个类型并没有真正用于其他任何东西,但是我认为它不是那么必要,它应该阻止你移动它枚举到单独的模块。 Windows的实现肯定可以跨越几个模块。如果你愿意,你甚至可以把它作为一个子包,即具有像

    这样的结构
    Window

    (根据您的需要进行调整)。