一个非常大的__init__有什么问题吗?

时间:2010-09-19 15:30:49

标签: python oop scope initialization abstraction

我正在编写一个带有使用Tkinter模块构建的GUI的Python程序。我正在使用一个类来定义GUI,因为它可以更容易地将命令传递给按钮,并使整个事情更容易理解。

我的GUI的实际初始化需要大约150行代码。为了使这更容易理解,我编写了__init__函数,如下所示:

def __init__(self, root):
    self.root = root
    self._init_menu()
    self._init_connectbar()
    self._init_usertree()
    self._init_remotetree()
    self._init_bottom()

其中_init_menu()_init_connectbar()等执行所有初始化工作。这使我的代码更易于遵循,并防止__init__变得过大。

但是,这会产生范围问题。由于我在_init_connectbar()中定义的Entry小部件位于函数范围内而不是类属性,因此我无法在类中的其他方法中引用它。

我可以通过__init__中的大部分初始化来消除这些问题,但是我将失去第一种方法所带来的抽象。

我应该展开__init__,还是找到另一种方法将小部件带入类范围?

4 个答案:

答案 0 :(得分:5)

将这些小部件引用中的一些存储在实例变量中或返回它们(最小的设置提醒你;你想减少耦合)并将它们存储在__init__中的局部变量中,然后将相关的那些作为参数传递给你后来的施工助手。后者更干净,但要求事物分离得足以让你创造一个能够实现的顺序。

答案 1 :(得分:2)

在我看来,您应该将小部件存储为实例变量,以便您可以从任何方法引用它们。与大多数编程语言一样,当函数变得太大时,可读性会降低,因此分割初始化代码的方法是个好主意。

当类本身对于一个源文件变得太大时,您也可以使用混合类拆分该类(类似于在C#中使用部分类)。

例如:

class MainGuiClass(GuiMixin_FunctionalityA, GuiMixin_FunctionalityB):
    def __init__(self):
        GuiMixin_FunctionalityA.__init__(self)
        GuiMixin_FunctionalityB.__init__(self)

当GUI包含不同的功能时(例如配置选项卡,执行选项卡或任何功能),这会派上用场。

答案 2 :(得分:1)

您应该查看builder-pattern这类内容。如果您的GUI很复杂,那么描述它会有一些复杂性。无论是复杂功能还是某些文件中的复杂描述都归结为相同。您可以尝试使其尽可能可读和可维护,根据我的经验,构建器模式在这里确实有帮助。

答案 3 :(得分:1)

为什么不制作需要引用的小部件,实例变量。这就是我自己做的事情,似乎是一种非常常见的做法。

e.g。

self.some_widget