首页 > 代码库 > 类的继承2(多继承,晕啊晕啊晕啊)

类的继承2(多继承,晕啊晕啊晕啊)

 

此篇接 类的继承-1,这块听得不是很明白,所以展开帖子记录下细节。

6.多继承的时候,父类是从左到右执行的。class Woman(People,Relation), 先执行People,再执行 Relation

话不多说,先上程序。我的疑惑在于:在定义Relation的时候,没有进行__init初始化,为什么可以直接调用self.name和obj.name

 

1. Man(People,Relation) 执行的时候,先去People里面找构造方法,进行__init的初始化,接着再执行程序,此时self.name=name已经存在,所以Relation中可以调用。

 

 

class People(object):
    def __init__(self,name):
        self.name=name

class Relation(object):
    def make_friends(self,obj):
        print("%s is making friend with %s"%(self.name,obj.name))

class Man(People,Relation):
    pass
class Woman(People,Relation):
    pass

m1=Man("Jack")
w1=Woman("Lily")
m1.make_friends(w1)

 运行结果:

Jack is making friend with Lily

 2.当把People,Relation调换顺序以后,发现程序还是可以正常执行。这是因为在Man(Relation,People)的时候,程序并没有真正开始执行,只是做了一些初始化的工作。

所以此时self.name=name已经存在了。在运行m1.make_friends(w1)的时候,程序才开始真正执行。所以也不会报错。

class People(object):
    def __init__(self,name):
        self.name=name

class Relation(object):
    def make_friends(self,obj):
        print("%s is making friend with %s"%(self.name,obj.name))

class Man(Relation,People):
    pass
class Woman(Relation,People):
    pass

m1=Man("Jack")
w1=Woman("Lily")
m1.make_friends(w1)

 运行结果:

Jack is making friend with Lily

 

3.接着修改函数,让Relation函数初始化的时候同时打印self.name. 此时因为People函数还没有初始化,所以找不到self.name,会报错。

证明当继承多个父类的时候,默认的执行顺序是从左到右执行的。

class People(object):
    def __init__(self,name):
        self.name=name

class Relation(object):
    def __init__(self,n):
        print(self.name)
    def make_friends(self,obj):
        print("%s is making friend with %s"%(self.name,obj.name))

class Man(Relation,People):
    pass
class Woman(Relation,People):
    pass

m1=Man("Jack")
w1=Woman("Lily")
m1.make_friends(w1)

 运行结果:

Traceback (most recent call last):
  File "<encoding error>", line 16, in <module>
  File "<encoding error>", line 7, in __init__
AttributeError: ‘Man‘ object has no attribute ‘name‘

 4. 想在搞明白obj.name是什么意思了。m1.make_friends(w1) 中传的是w1, obj.name实际上就是w1.name. 而w1.name已经初始化过了,所以不会报错。

不需要再定义obj.name的巧妙之处就在于:传的参数是w1.

class People(object):
    def __init__(self,name):
        self.name=name

class Relation(object):
    def make_friends(self,obj):
        print("%s is making friend with %s"%(self.name,obj.name))

class Man(Relation,People):
    pass
class Woman(Relation,People):
    pass

m1=Man("Jack")
w1=Woman("Lily")
m1.make_friends(w1)
print(w1.name)

 运行结果:

Jack is making friend with Lily
<class ‘__main__.Woman‘>
Lily

 

5.因为Lucy没有经过People的初始化,所以她也没有name属性,所以obj.name会报错。

class People(object):
    def __init__(self,name):
        self.name=name
        
class Relation(object):
    def make_friends(self,obj):
        print("%s is making friend with %s"%(self.name,obj.name))

class Man(Relation,People):
    pass
class Woman(Relation,People):
    pass

m1=Man("Jack")
w1=Woman("Lily")
m1.make_friends(‘Lucy‘)

 运行结果:

Traceback (most recent call last):
  File "<encoding error>", line 16, in <module>
  File "<encoding error>", line 7, in make_friends
AttributeError: ‘str‘ object has no attribute ‘name‘

 

至此,算是搞明白了。在后面的例子中还需要再慢慢消化。

 

类的继承2(多继承,晕啊晕啊晕啊)