只导入包的一部分以避免循环导入
Importing only part of a package to avoid circular import
我 运行 陷入循环导入问题,因为我只需要导入包的一部分。当我的程序启动时,我创建了一个驱动程序 class,它继承自包中定义的 class,但该包的另一个不相关部分导入了驱动程序;我需要停止 运行ning 包中不相关的部分,直到以后需要它。
更多信息:我的程序中有一个接口包。它们只是具有我程序中许多对象共有的方法和属性的父对象。除了具有相似的目的外,它们没有任何逻辑联系。它们放在一个包裹里只是为了我方便;我不希望顶层有大量的 .py 文件,而宁愿将它们分类到子文件夹中。
包裹看起来像这样:
interfaces
__init__.py
destroyinterface.py
graphicsinterface.py
而 __ init __.py 看起来像这样:
from destroyinterface import DestroyInterface
from graphicsinterface import GraphicsInterface
我想在 graphicsinterface.py 未初始化的情况下导入 DestroyInterface。 graphicsinterface.py 导入依赖于 DestroyInterface 的驱动程序,但我似乎无法在 graphicsinterface.py 未初始化的情况下访问 DestroyInterface 来创建驱动程序。
我不想从 __ init __.py 中删除 GraphicsInterface 导入,因为我不想让它们在导入时必须知道它位于一个名为 graphicsinterface.py 的文件中.将有关我的包结构的信息包含到每个单独的导入中既增加了样板文件又使重构变得更加困难。我希望 classes 可以直接从接口模块导入,但它们的 .py 文件只有在我明确访问它们时才会被初始化。
我也不想在 graphicsinterface.py 中使用惰性导入驱动程序,既因为它很乱(我只希望在我真正需要它时初始化文件),也因为在GraphicsInterface 的时间敏感方法会减慢它们的速度。
我运气不好吗?我必须以不同的方式对我的文件进行排序吗?
我建议在图形界面中查看两个解决方案。首先,如果只有几个函数需要驱动程序,请在这些函数中导入驱动程序。导入一个已经导入的模块是高效的,所以在驱动程序中导入它应该没问题。
另一种方法是在图形界面中做这样的事情:
driver = None # filled in when driver is imported
然后在别处
import driver
import interfaces.graphics
interfaces.graphics.driver = driver
所以我遇到了一个 hack 来解决我的问题。我想我会分享它。
我的 __ 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()
这使得来自该包的任何导入语句都引用在那里定义的对象的属性,从而延迟文件的初始化,直到显式导入。不知道这是否适用于 python 3,一开始这可能是个糟糕的主意,但它对我有用。愿上帝怜悯我的灵魂。
我 运行 陷入循环导入问题,因为我只需要导入包的一部分。当我的程序启动时,我创建了一个驱动程序 class,它继承自包中定义的 class,但该包的另一个不相关部分导入了驱动程序;我需要停止 运行ning 包中不相关的部分,直到以后需要它。
更多信息:我的程序中有一个接口包。它们只是具有我程序中许多对象共有的方法和属性的父对象。除了具有相似的目的外,它们没有任何逻辑联系。它们放在一个包裹里只是为了我方便;我不希望顶层有大量的 .py 文件,而宁愿将它们分类到子文件夹中。
包裹看起来像这样:
interfaces
__init__.py
destroyinterface.py
graphicsinterface.py
而 __ init __.py 看起来像这样:
from destroyinterface import DestroyInterface
from graphicsinterface import GraphicsInterface
我想在 graphicsinterface.py 未初始化的情况下导入 DestroyInterface。 graphicsinterface.py 导入依赖于 DestroyInterface 的驱动程序,但我似乎无法在 graphicsinterface.py 未初始化的情况下访问 DestroyInterface 来创建驱动程序。
我不想从 __ init __.py 中删除 GraphicsInterface 导入,因为我不想让它们在导入时必须知道它位于一个名为 graphicsinterface.py 的文件中.将有关我的包结构的信息包含到每个单独的导入中既增加了样板文件又使重构变得更加困难。我希望 classes 可以直接从接口模块导入,但它们的 .py 文件只有在我明确访问它们时才会被初始化。
我也不想在 graphicsinterface.py 中使用惰性导入驱动程序,既因为它很乱(我只希望在我真正需要它时初始化文件),也因为在GraphicsInterface 的时间敏感方法会减慢它们的速度。
我运气不好吗?我必须以不同的方式对我的文件进行排序吗?
我建议在图形界面中查看两个解决方案。首先,如果只有几个函数需要驱动程序,请在这些函数中导入驱动程序。导入一个已经导入的模块是高效的,所以在驱动程序中导入它应该没问题。 另一种方法是在图形界面中做这样的事情:
driver = None # filled in when driver is imported
然后在别处
import driver
import interfaces.graphics
interfaces.graphics.driver = driver
所以我遇到了一个 hack 来解决我的问题。我想我会分享它。
我的 __ 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()
这使得来自该包的任何导入语句都引用在那里定义的对象的属性,从而延迟文件的初始化,直到显式导入。不知道这是否适用于 python 3,一开始这可能是个糟糕的主意,但它对我有用。愿上帝怜悯我的灵魂。