需要了解Python的继承机制我们需要先从Python的变量绑定机制说起。与其他静态语言不同的是其本身的变量都是“绑定”在一个对象上的。好比是一块磁铁,看似是一个整体实质不是。

浅析Python中的继承机制

init 注意事项

class A:
    def __init__(self):
        self.name = "A"
    def PrintName(self):
        print self.name
    
class B(A):
    def __init__(self):
        A.__init__(self)
        self.__age = 18
    
    
obj = B()
obj.PrintName()

__init__并不相当于Java中的构造函数,执行它的时候,实例已构造出来了。

class A(object):
    def __init__(self,name):
        self.name=name
    def getName(self):
        return 'A '+self.name

当我们执行

a=A('hello')

时,可以理解为

a=object.__new__(A)
A.__init__(a,'hello')

即__init__作用是绑定已实例化后的对象。

子类可以不重写init,实例化子类时,会自动调用超类中已定义的__init__

class B(A):
    def getName(self):
        return 'B '+self.name
 
if __name__=='__main__':
    b=B('hello')
    print b.getName()

但如果重写了__init__,实例化子类时,则不会隐式的再去调用超类中已定义的__init__

class C(A):
    def __init__(self):
        pass
    def getName(self):
        return 'C '+self.name
 
if __name__=='__main__':
    c=C()
    print c.getName()

则会报”AttributeError: ‘C’ object has no attribute ‘name’”错误,所以如果重写了__init__,为了能使用或扩展超类中的行为,最好显式的调用超类的__init__方法

class C(A):
    def __init__(self,name):
        super(C,self).__init__(name)
    def getName(self):
        return 'C '+self.name
 
if __name__=='__main__':
    c=C('hello')    
    print c.getName()

补充

python类有经典类和新式类

  1. 经典类

没有继承的类, 注意:如果经典类被作为父类,子类调用父类的构造函数时会出错。【TypeError: must be type, not classobj】

#基类(经典类)
class Person:
    def __init__(self):
        print "Hi, I am a person. "

#子类
class Student(Person):
    def __init__(self):
        super(self.__class__, self).__init__()

if __name__ == "__main__":
    student = Student()
    #出错啦!TypeError: must be type, not classobj
  1. 新式类

    每个类都继承于一个基类,可以是自定义类或者其它类,如果什么都不想继承,那就继承于object 如果想用super调用父类的构造函数,请使用新式类!

#基类(新式类)
class Person(object):
    def __init__(self):
        print "Hi, I am a person."

#子类
class Student(Person):
    def __init__(self):
        super(self.__class__, self).__init__()

if __name__ == "__main__":
    student = Student()

参考与引用: