问题
I've dug myself into quite a hole here.
I'm working on a Python/Kivy app in PyDev.
The app runs off of many systems (about 10), so I shoved them into an engine to handle everything.
For ease of access, I grab the engine via (the worst) singletons
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
Unfortunatley, this resulted in some nasty circular dependencies.
Main has to create engine, and know about it, which runs engines imports, which runs the system imports. Problem: Systems imports then import engine, circular reference.
system1.py
#system1.py
from code import engine
class System1():
def SomeMethod(self):
engine.GetInstance().mSystem2.DoThings()
You get the picture. I bypassed this for now with this hideous code all over the place:
system1.py
#system1.py
class System1():
def SomeMethod(self):
from code import engine
engine.GetInstance().mSystem2.DoThings()
This stops the import from happening until that line, which is fine, but it looks wrong, eveyrthing feels like i'm doing things wrong.
I'm tempted to just pass Engine as a reference to every systems constructor, but thats a bit of refactoring, and i'd like to know if there's a more decent way to fix this sort of singleton/circular reference issue for the future.
回答1:
How about having a "registration" mechanism, where each system
module "registers" itself with the Engine
class using some module-level code:
engine.py
class Engine():
@classmethod
def register(cls, type):
...
system1.py
from engine import Engine
class System1():
...
Engine.register(System1)
That way, the Engine
doesn't directly have to know what gets plugged into it.
来源:https://stackoverflow.com/questions/15216424/python-circular-dependencies-and-singletons