[英]Python classes: Inheritance vs Instantiation
I'm creating a GUIclass that uses Frame() as its base class. 我正在创建一个使用Frame()作为基类的GUIclass。
In my GUIclass's init method I want to create a Frame widget 在我的GUIclass的init方法中,我想创建一个Frame小部件
Right now I have: 现在我有:
class GUIclass(Frame):
def __init__(self, parent):
frame = Frame(self, parent)
But I've seen this elsewhere for the third line: 但我在其他地方见过第三行:
Frame.__init__(self, parent)
I'm new to programming, python and definitely inheritance and I wanted to know if I understand the difference between the two correctly. 我是编程,python和绝对继承的新手,我想知道我是否正确理解了两者之间的区别。 I did a lot of researching and reading, I promise, but I couldn't quite find anything that made it completely clear: 我保证,我做了大量的研究和阅读,但我找不到任何能让它完全清楚的东西:
In the first situation I don't call the init method as I created a Frame object (frame) and when an object is created its init method is called implicitly by python. 在第一种情况下,我没有调用init方法,因为我创建了一个Frame对象(frame),当创建一个对象时,它的init方法被python隐式调用。
In the second scenario, one is calling the init method on the class (which I believe is totally legit?) because a Frame object wasn't created, so therefore wouldn't do it automatically. 在第二个场景中,一个是在类上调用init方法(我认为这是完全合法的?),因为没有创建Frame对象,因此不会自动执行。
Is that right? 那正确吗?
I've also seen: 我也看到了:
frame = Frame.__init__(self, parent)
which really threw me off. 这真的让我失望了。 Is this just someone doing something redundant or is there a reason for this? 这只是某人做了多余的事情还是有理由这样做?
Thank you for your help, I want to take it slow for now and make sure I fully understand any and every line of code I write as I go rather than writing and running a whole program I half understand. 感谢您的帮助,我想暂时放慢速度并确保我完全理解我编写的任何代码行,而不是编写和运行我理解的整个程序。
You should call 你应该打电话
super(GUIclass, self).__init__(parent)
This is the proper way to call (all) your inherited __init__()
method(s). 这是调用(全部)继承的__init__()
方法的正确方法。 It has in many cases identical results compared to the mentioned 与上述相比,它在许多情况下具有相同的结果
Frame.__init__(self, parent)
which only lacks the abstraction concerning the inheritance relationships and states the class Frame
as the one and only class whose __init__()
method you might want to call (more about that later). 它只缺少有关继承关系的抽象,并将类Frame
为您可能想要调用的__init__()
方法的唯一类(稍后会详细介绍)。
The also mentioned 还提到了
frame = Frame(self.parent)
is wrong in this context. 在这种情况下是错误的。 It belongs to another pattern of object relationship, namely contents relationship instead of inheritance relationship (which you aim at). 它属于另一种对象关系模式,即内容关系而不是继承关系(你的目标)。 It will create a new object of class Frame
instead of initializing the Frame
parts of yourself; 它将创建一个Frame
类的新对象,而不是初始化自己的Frame
部分; in inheritance relationships you are a Frame
, so you have to initialize yourself
as one as well as initializing your specialized parts (which is done in the rest of your __init__()
method). 在继承关系中,你是一个Frame
,所以你必须将yourself
初始化为一个以及初始化你的专用部分(这在你的__init__()
方法的其余部分完成)。 In contents relationship models you merely have a Frame
. 在内容关系的模型,你只是有一个Frame
。
Now, what about that "slight" difference I mentioned above between calling super(GUIclass, self).__init__(parent)
and Frame.__init__(self, parent)
? 现在,我在调用super(GUIclass, self).__init__(parent)
和Frame.__init__(self, parent)
之间提到的“轻微”差异怎么样?
To understand that you need to dig deeper into inheritance relationships and the various possibilities these offer, especially with multiple inheritance. 要了解您需要深入了解继承关系及其提供的各种可能性,尤其是多重继承。
Consider a diamond-shaped relationship model which looks like this: 考虑一个菱形关系模型,如下所示:
Frame
/ \
GUIclass SomeOtherClass
\ /
AnotherClass
In your current scenario you only have the top left two classes, but one never knows what's going to come, and you should always code in a way so that the next user of your code keeps all options. 在您当前的场景中,您只有左上角的两个类,但是一个人永远不知道会发生什么,并且您应该总是以某种方式编写代码,以便代码的下一个用户保留所有选项。
In this diamond-shaped pattern you have AnotherClass
which inherits GUIClass
and SomeOtherClass
which in turn both inherit Frame
. 在这个菱形图案中,你有AnotherClass
继承GUIClass
和SomeOtherClass
GUIClass
,它们都继承了Frame
。
If you now use the pattern Frame.__init__(self, parent)
in both GUIclass
and SomeOtherClass
, then calling their __init__()
methods from the __init__()
method of AnotherClass
will result in a doubled calling of the Frame
's __init__()
method. 如果你现在使用的模式Frame.__init__(self, parent)
在这两个GUIclass
和SomeOtherClass
,然后把他们的__init__()
从方法__init__()
的方法AnotherClass
将导致的一倍调用Frame
的__init__()
方法。 This typically is not intended, and to take care that this does not happen, the super
call was invented. 这通常不是预期的,并且为了不会发生这种情况,发明了super
呼叫。 It takes care that a decent calling order calls each of the __init__()
methods only and exactly once. 注意一个体面的调用命令只调用每个__init__()
方法并且只调用一次。
你必须使用Frame.__init__(self, parent)
因为Tkinter不支持超级调用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.