仅导入包的一部分以避免循环导入

时间:2017-04-29 13:50:56

标签: python import package circular-dependency

我遇到了循环导入问题,因为我只需要导入部分包。当我的程序启动时,我创建了一个继承自包中定义的类的驱动程序类,但该包的另一个不相关的部分导入了驱动程序;我需要阻止程序包中不相关的部分运行,直到以后需要它为止。

更多信息:我的程序中有一个接口包。它们只是具有我的程序中许多对象共有的方法和属性的父对象。除了具有类似目的之外,它们没有逻辑连接。它们只是为了我的方便而在一个包装中;我不想在顶层使用大量的.py文件,而是将它们分类到子文件夹中。

包看起来像这样:

interfaces __init__.py destroyinterface.py graphicsinterface.py

__ init __.py看起来像这样:

from destroyinterface import DestroyInterface from graphicsinterface import GraphicsInterface

我想导入DestroyInterface而没有初始化graphicsinterface.py。 graphicsinterface.py导入依赖于DestroyInterface的驱动程序,但我似乎无法访问DestroyInterface来创建没有初始化graphicsinterface.py的驱动程序。

我不想从__ init __.py中删除GraphicsInterface导入,因为我不想让它们在导入时必须知道它存在于一个名为graphicsinterface.py的文件中。在每个导入中包含有关我的包结构的信息都会增加样板并使重构变得更加困难。我希望可以直接从interfaces模块访问这些类,但只有在我明确访问它们时才会初始化它们的.py文件。

我也不想在graphicsinterface.py中使用延迟导入的驱动程序,因为它很乱(我只想在实际需要时初始化文件)并且因为在时间敏感方法中导入GraphicsInterface会降低它们的速度。

我运气不好吗?我是否必须以不同的方式对文件进行排序?

2 个答案:

答案 0 :(得分:0)

我建议在图形界面中查看两个解决方案。首先,如果只有几个函数需要驱动程序,请在这些函数中导入驱动程序。导入已导入的模块是有效的,因此在驱动程序中导入它应该没问题。 另一种方法是在图形界面中执行类似的操作:

driver = None # filled in when driver is imported

然后在其他地方

import driver
import interfaces.graphics
interfaces.graphics.driver = driver

答案 1 :(得分:0)

所以我遇到了一个黑客来解决我的问题。我想分享它。

我的__ init __.py现在看起来像这样:

class CrazyHack(object): @property def DestroyInterface(self): import crazyhackthing.destroyinterface return destroyinterface.DestroyInterface @property def GraphicInterface(self): import crazyhackthing.graphicinterface return graphicinterface.GraphicInterface import sys sys.modules["crazyhackthing"] = sys.modules["interfaces"] sys.modules["interfaces"] = CrazyHack()

这使得此包中的任何import语句都引用了那里定义的对象的属性,从而延迟了文件的初始化,直到显式导入。不知道这是否适用于python 3,并且它首先可能是一个糟糕的主意,但它对我有用。愿上帝怜悯我的灵魂。