Python、循环依赖与单例模式
我现在陷入了一个麻烦的境地。
我正在用Python和Kivy开发一个应用,使用的是PyDev这个工具。
这个应用需要运行在大约10个系统上,所以我把它们放进一个引擎里来处理所有的事情。
为了方便访问,我通过(最糟糕的)单例模式来获取这个引擎。
main.py
#main.py
from code import engine
class MyApp(App):
def build(self):
engine.GetInstance().Initialize()
if __name__ == '__main__':
MyApp().run()
engine.py
#engine.py
from code import system1
from code import system2
gEngineInstance = None
def GetInstance():
global gEngineInstance
if (gEngineInstance == None):
gEngineInstance = Engine()
return gEngineInstance
class Engine():
mSystem1 = None
mSystem2 = None
def Initialize(self):
self.mSystem1 = system1.System1()
self.mSystem2 = system2.System2()
# Omitted
不幸的是,这导致了一些麻烦的循环依赖。
主程序需要创建引擎,并且要知道引擎的存在,这样引擎才能导入其他模块,而这些模块又需要导入引擎。
问题是:系统模块又要导入引擎,这就形成了循环引用。
system1.py
#system1.py
from code import engine
class System1():
def SomeMethod(self):
engine.GetInstance().mSystem2.DoThings()
你能理解我的意思。
为了暂时解决这个问题,我在代码里到处写了一些丑陋的代码:
system1.py
#system1.py
class System1():
def SomeMethod(self):
from code import engine
engine.GetInstance().mSystem2.DoThings()
这样做可以在那行代码之前阻止导入,这样虽然可以,但看起来不太对劲,感觉我在做错事。
我很想把引擎作为一个引用传递给每个系统的构造函数,但这需要一些重构。我想知道有没有更好的方法来解决这种单例和循环引用的问题,以便将来能避免。
1 个回答
2
我们可以想象有一个“注册”机制,每个 system
模块都可以用一些模块级别的代码来“注册”自己给 Engine
类:
engine.py
class Engine():
@classmethod
def register(cls, type):
...
system1.py
from engine import Engine
class System1():
...
Engine.register(System1)
这样一来,Engine
就不需要直接知道它里面接入了什么东西。