问题:

     使用了文档tkinter.pdf中的例子,并稍作修改如下:

#!/usr/bin/env python
import Tkinter as tk
class Application(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self,  master)
        # super(self.__class__, self).__init__( master )
                                                                                                                                                                                                                                                                                                                        
        self.grid()
        self.createWidgets()
    def createWidgets(self):
        self.quitButton = tk.Button(self, text='Quit', command=self.quit)
        self.quitButton.grid()
app = Application()
app.master.title('Sample')
app.mainloop()

     为了防止显式声明父类的名字,使用super()工厂函数,super的第一个参数需要提供类型或类的名称,使用了self.__class__(也是为了不显式使用类名字)。

结果运行时,在super一行出现错误:


TypeError: must be type, not classobj


验证:

一开始以为super用错了呢,自己编写了个例子:

class A(object):
    def __init__(self, master=None):
        print 'a'
class B(A):
    def __init__(self, master=None):
        super(self.__class__, self).__init__(master)
        print 'b'
b = B()

运行没有问题,很奇怪。


原因:

后来在stackoverflow上搜索类似的问题,发现问题是:

1. python2中的Tkinter是用旧式类实现的(文档中没有写),也就是说,Tkinter并没有继承自object,而是类似:

class Tkinter:
    ...

2. super不能调用旧式类;

3. 使用旧式类调用父类的__init__()时,也需要使用self作为第一个参数;

4. 使用python3就可以使用新式类调用tkinter(首字母小写)了。


而且,网上查找时还发现:在python3中,还能使用super().__init__()这样来调用父类构造器,不用告诉super当前类的名称。


看样子,过段时间可以开始考虑使用Python3了,有更多方便的语法。虽然好多代码还是用python2写的,例如IronPython。不过对我没有啥影响:D