【问题标题】:Python, Circular Dependencies, and SingletonsPython、循环依赖和单例
【发布时间】:2013-02-19 10:02:50
【问题描述】:

我在这里挖了一个坑。

我正在 PyDev 中开发 Python/Kivy 应用程序。

该应用程序在许多系统(大约 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

不幸的是,这导致了一些令人讨厌的循环依赖。

Main 必须创建引擎,并且知道它,它运行引擎导入,运行系统导入。 问题:系统导入然后导入引擎,循环引用。

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()

这会阻止导入发生,直到该行,这很好,但它看起来不对,每件事都感觉我做错了。

我很想将 Engine 作为每个系统构造函数的引用传递,但这有点重构,我想知道是否有更体面的方法来解决这种单例/循环引用问题未来。

【问题讨论】:

    标签: python import singleton circular-dependency kivy


    【解决方案1】:

    拥有一个“注册”机制怎么样,每个system 模块使用一些模块级代码向Engine 类“注册”自己:

    engine.py

    class Engine():
        @classmethod
        def register(cls, type):
            ...
    

    system1.py

    from engine import Engine
    
    class System1():
        ...
    
    Engine.register(System1)
    

    这样,Engine 不必直接知道插入了什么。

    【讨论】:

    • 这是……一个有趣的想法。关于这些动态语言的一些事情对我来说很难处理,但有时,没有严格的类型是一个非常方便的工具。我会试一试,谢谢!
    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 2020-11-18
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    相关资源
    最近更新 更多