如何避免在Python中的构造函数之间传递属性?

mxw*_*ion 2 python software-design python-3.6

class A(SomeBaseClass):
    def __init__(self):
        super().__init__()
        self._attribute_0 = something_0
        self._attribute_1 = something_1
        # etc.

    def some_method(self) -> None:
        do_something()
Run Code Online (Sandbox Code Playgroud)

现在假设您有类似的类B, C, D, etc.(并非所有类都继承自同一基类)。它们都具有一些各自的功能,并且从逻辑的角度来看,它们很好地封装在这些类中。关键的一点是,对于这些类中的每一个,一次总是只有一个实例存在。问题是,有时一个类需要访问另一个类的函数,即

if __name__ == "__main__":
    a = A()
    b = B(a)
    c = C()
    d = D(c, a)
    b.d = d
    etc.

Run Code Online (Sandbox Code Playgroud)

假设存在多个 class 实例,这段代码对我来说是合理的A, B, etc.,但由于一次总是只有一个实例存在,因此总是在构造函数中传递它们似乎有点多余(实际上,这些类当然有更复杂的名称)并且“main”函数变得非常难以阅读......)。

尽管存在争议,但在其他语言中,一种解决方案是辛格尔顿模式。似乎有一些方法可以在Python中实现单例(参见这里),但它们似乎不被鼓励(即有些人甚至说Python中永远不需要它们)。

我的目标相当简单:我希望我的对象a,b,c, etc.可以在整个项目中访问,而不必在构造函数中传递它们或通过 等来一一设置它们b.d = d

这在Python中可能吗?我有什么选择?


@blue_note 的回答插图

# objects.py
a = A()
b = B(a)
c = C()
d = D(c, a)
b.d = d
Run Code Online (Sandbox Code Playgroud)

然后当你在其他地方需要它们时:

# foo.py
from objects.py import a

class Foo:
    def __init__(self):
        # use a
Run Code Online (Sandbox Code Playgroud)

blu*_*ote 6

只需在单个模块中初始化对象,然后从那里导入它们即可。python 模块中的代码在第一次导入时运行,并且结果被缓存。因此,在后续导入中,所有模块都保证访问对象的同一实例。