问题:
使用了文档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