派生出类有一些方法覆盖问题,以及调用基类的方法
__author__ = 'LiHui' class MyBook(object): def __init__(self): print 'MyBook __init__' class MyCookBook(MyBook): def __init__(self): print 'MyCookBook __init__' if __name__ == '__main__': MyCookBook()
这里MyCookBook由类MyBook派生,但是他们却有着相同命名的构造器__init__方法,那么尽管子类里继承了基类的__init__,但由于子类里定义了相同的__init__方法,那么基类里的__init__就会被覆盖,输出结果
MyCookBook __init__
假如做一些改编,将子类的__init__重命名
__author__ = 'LiHui' class MyBook(object): def __init__(self): print 'MyBook __init__' class MyCookBook(MyBook): def foo(self): print 'MyCookBook __init__' if __name__ == '__main__': MyCookBook()
这里将__init__修改为foo,输出结果为
MyBook __init__
可见这时候不存在构造器方法覆盖问题,而且foo没有通过类实例来调用,所以不会打印其函数信息,但是最终打印了基类构造器的输出信息,这里说明了,如果从带有构造器__init__的基类里派生出一个子类,假如不去覆盖掉__init__,它将会被继承,并自动调用
假如想在子类里调用基类方法,可以通过super()方法来实现,不仅能找到对应的基类,而且还能传进去self,这样,就可以在子类里通过super()来调用基类方法,最终只需要操作子类
__author__ = 'LiHui' class MyBook(object): def __init__(self): print 'MyBook __init__' class MyCookBook(MyBook): def __init__(self): super(MyCookBook, self).__init__() print 'MyCookBook __init__' if __name__ == '__main__': MyCookBook()
这样就能输出结果
MyBook __init__ MyCookBook __init__
但是,下面这种指出基类并调用方法的方式,也能得出结果
__author__ = 'LiHui' class MyBook(object): def __init__(self): print 'MyBook __init__' class MyCookBook(MyBook): def __init__(self): MyBook.__init__(self) print 'MyCookBook __init__' if __name__ == '__main__': MyCookBook()
这里看上去更醒目,但是维护起来不如super那么直接,假如后来有修改基类名字,super根本不需要关心你的修改,而这种方式必须重新查看修改后的类名,而且假如有很多出都有这种调用方式,改动还是较多的
但是有一点要注意的就是,如果是这种传递方法,调用基类方法的时候一定要传递一个self参数,否则会出现下面报错
TypeError: unbound method foo() must be called with MyBook instance as first argument (got nothing instead)