我正在创建一个使用Frame()作为基类的GUI类。
在我的GUIclass的init方法中,我想创建一个Frame小部件
现在我有:
class GUIclass(Frame):
def __init__(self, parent):
frame = Frame(self, parent)
但我在其他地方已经看到了第三行:
Frame.__init__(self, parent)
我是编程,python和绝对继承的新手,我想知道我是否正确理解了两者之间的区别。我承诺,我做了很多研究和阅读,但我找不到任何能让它完全清楚的东西:
在第一种情况下,我没有调用init方法,因为我创建了一个Frame对象(frame),当创建一个对象时,它的init方法被python隐式调用。
在第二个场景中,一个是在类上调用init方法(我认为这是完全合法的?),因为没有创建Frame对象,因此不会自动执行。
是对的吗?
我也看到了:
frame = Frame.__init__(self, parent)
这真的让我失望了。这只是某人做多余的事情还是有理由这样做?
感谢您的帮助,我想暂时放慢速度并确保我完全理解我编写的任何代码行,而不是编写和运行整个程序,我不明白。
你应该打电话
super(GUIclass, self).__init__(parent)
这是调用(全部)继承的正确方法 __init__()
方法)。在许多情况下,与上述相比,它具有相同的结果
Frame.__init__(self, parent)
它只缺少关于继承关系的抽象,并说明了类 Frame
作为独一无二的班级 __init__()
您可能想要调用的方法(稍后会详细介绍)。
还提到了
frame = Frame(self.parent)
在这种情况下是错误的。它属于另一种对象关系模式,即 内容 关系而不是 遗产 关系(你的目标)。它会 创建 一个新的阶级对象 Frame
而不是初始化 Frame
你自己的一部分;在继承关系中你 是 一个 Frame
,所以你必须初始化 yourself
作为一个以及初始化你的专业部分(这是在你的其余部分完成) __init__()
方法)。在 内容 关系模型你只是 有 一个 Frame
。
现在,我之间在调用之间提到的“轻微”差异呢 super(GUIclass, self).__init__(parent)
和 Frame.__init__(self, parent)
?
要了解您需要深入了解继承关系及其提供的各种可能性,尤其是多重继承。
考虑一个菱形关系模型,如下所示:
Frame
/ \
GUIclass SomeOtherClass
\ /
AnotherClass
在您当前的场景中,您只有左上角的两个类,但是一个人永远不知道会发生什么,并且您应该总是以某种方式编写代码,以便代码的下一个用户保留所有选项。
在这个菱形图案中你有 AnotherClass
继承 GUIClass
和 SomeOtherClass
而这又继承了 Frame
。
如果您现在使用该模式 Frame.__init__(self, parent)
同时 GUIclass
和 SomeOtherClass
然后打电话给他们 __init__()
来自的方法 __init__()
的方法 AnotherClass
将导致双倍的呼叫 Frame
的 __init__()
方法。这通常不是预期的,并且要注意不会发生这种情况, super
电话是发明的。一个体面的调用命令会调用每个调用它 __init__()
方法只有一次。
你必须使用 Frame.__init__(self, parent)
因为Tkinter不支持超级电话