Python2.7中的super方法浅见

来源:互联网 发布:java jvm 工作原理 编辑:程序博客网 时间:2024/06/11 05:04

重写是继承机制中的重要内容,对于构造方法尤为重要。构造方法用来初始化新建对象的状态,大多数子类不仅要有自己的初始化代码,还要拥有超类的初始化代码。
如果一个类的构造方法被重写,那么就需要调用超类的构造方法,否则对象可能不会被正确的初始化–Python基础教程

将上述思想进行实践.
python 2.7
IDE Pycharm 5.0.3
当前,我们先定义一个大的父类,用Bird来创建,里面有个构造方法和定义了两个方法,分别是eat,sing方法,然后创建了一个Sparrow的子类,继承自父类Bird,自己也拥有构造方法,首先进行测试

class Bird:    def __init__(self):        print '我是父类的初始化'        self.cansing = True    def eat(self):        print 'i can eat'    def sing(self):        if self.cansing:            print 'i can sing'class Sparrow(Bird):    def __init__(self):        print '我就是要重写父类的init'    def jump(self):        print 'i can jump'S = Sparrow()S.jump()S.eat()S.sing()

这里写图片描述
然后很喜闻乐见的报错了,因为子类重写了父类的构造方法,我的理解是被覆盖了而不是像append那样接上,所以结果如图:
这里显示了能够正常调用父类的其他方法,但是构造方法被重写后调用不了
这里的解决方法就存在两种,一种是调用未绑定的超类构造方法,这个方法在python2.2使用较多,之后随着super出现后,被取缔,原因也有很多,这个具体自己百度吧。
先放上用未绑定的超类构造方法:

class Bird:    def __init__(self):        print '我是父类的初始化'        self.cansing = True    def eat(self):        print 'i can eat'    def sing(self):        if self.cansing:            print 'i can sing'class Sparrow(Bird):    def __init__(self):        Bird.__init__(self)        print '我就是要重写父类的init'    def jump(self):        print 'i can jump'S = Sparrow()S.jump()S.eat()S.sing()

效果如下,可以看出,父类的构造方法被调用,这才是我们真正需要的继承方法,即像append那样填充式继承。
这里写图片描述
这里写图片描述
这个方法个人来看并不推荐,因为如果要修改很多很多子类,若是父类名字一变,修改量太大,而且,对父类的访问着实很多次。
另一种方式就是使用super,记得这是个只能在新式类中才起作用,所以代码块前需要加

__metaclass__ = type

完整代码块如下:

__metaclass__ = typeclass Bird:    def __init__(self):        print '我是父类的初始化'        self.cansing = True    def eat(self):        print 'i can eat'    def sing(self):        if self.cansing:            print 'i can sing'class Sparrow(Bird):    def __init__(self):        super(Sparrow,self).__init__()        print '我就是要重写父类的init'    def jump(self):        print 'i can jump'S = Sparrow()S.jump()S.eat()S.sing()

效果和上述采用未绑定的超类方法一样,但是更加直观。下面盗用一下为什么super方法那么超级:
即使类已经继承多个超类,它也只需要使用一次super函数

6.29更新–关于Tkinter中Frame类是旧类的判断
接触Tk,看着教程写到:

def __init__(self, master=None):        Frame.__init__(self, master)

想着能不能用super的方法呢,不是一直在提倡super么,结果试了一下,

def __init__(self,master=None):        super(Application, self).__init__()

报错:

TypeError: must be type, not classobj

结果查看了一下父类Frame类型;

In[3]: issubclass(Frame, object)#判断是否为新类Out[3]: False

显示Frame是旧类,所以不能和新类混着用,这里记上一笔。

原创粉丝点击