Python 子类化时使用(误用)super()

Python 子类化时使用(误用)super(),python,tkinter,class-hierarchy,Python,Tkinter,Class Hierarchy,当我绞尽脑汁想如何对tkinterFrame和LabelFrame进行子类化,让它们坐在正确的父对象上时,我发现很多答案表明super() 所以我试了一下,想看看大惊小怪是怎么回事,但似乎根本不起作用。在Python2.7中,它抱怨参数的类型。在3.4中,它说master有多种定义。由于super的注释如下所示,它的工作原理与预期一致。我做错了什么 # import Tkinter as tki # py 2.7 import tkinter as tki # py 3.4 class

当我绞尽脑汁想如何对tkinter
Frame
LabelFrame
进行子类化,让它们坐在正确的父对象上时,我发现很多答案表明
super()

所以我试了一下,想看看大惊小怪是怎么回事,但似乎根本不起作用。在Python2.7中,它抱怨参数的类型。在3.4中,它说master有多种定义。由于super的注释如下所示,它的工作原理与预期一致。我做错了什么

# import Tkinter as tki   # py 2.7
import tkinter as tki   # py 3.4

class App(tki.LabelFrame):
    def __init__(self, parent):
        tki.LabelFrame.__init__(self, master=parent, text='inner')
        # super().__init__(self, master=parent, text='inner')          #py 3.4
        # super(App, self).__init__(self, master=parent, text='inner') #py 2.7
        # super(App, self).__init__(master=parent, text='inner') #py 2.7

        self.quit = tki.Button(self, text='quit', command=exit)
        self.quit.grid()      

if __name__ == '__main__':    
    root = tki.Tk()
    root.title('nesting testing')

    outer = tki.LabelFrame(root, text='outer level')
    outer.pack()

    app = App(outer)
    app.pack()

    root.mainloop()
在调用
super()时删除
self
。\uuuu init\uuuu()
是我尝试的第一件事,但在py2.7中,我仍然收到相同的错误消息,不管它是否在那里

self

Traceback (most recent call last):  
    File "C:\Python\TESTS\test_super.py", line 21, in <module>  
        app = App(outer)  
    File "C:\Python\TESTS\test_super.py", line 9, in __init__  
        super(App, self).__init__(master=parent, text='inner') #py 2.7  
TypeError: must be type, not classobj
Traceback (most recent call last):  
  File "C:\Python\TESTS\test_super.py", line 21, in <module>  
    app = App(outer)  
  File "C:\Python\TESTS\test_super.py", line 8, in __init__  
    super(App, self).__init__(self, master=parent, text='inner') #py 2.7  
TypeError: must be type, not classobj  

错误消息保持与我删除self相同的事实表明这不是问题所在,但它在基类调用中正常工作的事实让我对其他参数可能有什么问题感到困惑。

以这种方式使用
super
时,不会显式传递
self
。只需执行
super(App,self)。\uuuuu init(master=parent,text='inner')
(或者
super()。\uuuu init(master=parent,text='inner')
,适用于Python 3)。

如果我没记错的话

super().__init__(self, master=parent, text='inner')          #py 3.4
super(App, self).__init__(self, master=parent, text='inner') #py 2.7
本应是—

super().__init__(master=parent, text='inner')          #py 3.4
super(App, self).__init__(master=parent, text='inner') #py 2.7
因为您不应该将
self
作为参数传递给super的
\uuuu init\uuuu

事实上,在使用实例方法时,您不应该显式地将
self
传递给任何方法,
self
在解释器调用时自动提供

顺便说一句

所有这些电话都是多余的。您应该只使用其中一个。我宁愿-

    super().__init__(master=parent, text='inner')          #py 3.4

但是如果你喜欢使用第一个-

    tki.LabelFrame.__init__(self, master=parent, text='inner')
确保您移除了自我,并使其-

    tki.LabelFrame.__init__(master=parent, text='inner')

我编辑了问题以显示测试结果,我一定是做错了什么?更新了我的答案,请检查。如果我尝试不带self的super(),它告诉我缺少位置参数self,至少在3.4中是这样。也许我应该停止抨击tkinter类,因为它们的行为似乎不像它们应该的那样,而只是使用有效的方法。总结一下@Veedrac中非常有用的链接:在Python2.7中,你不能对该类使用
super
,因为它是一个“旧式”类(它不是从
对象继承的)。在Python3中,所有类都是“新样式”,因此
super
可以工作(包括新的无参数版本)。
    tki.LabelFrame.__init__(self, master=parent, text='inner')
    tki.LabelFrame.__init__(master=parent, text='inner')