此篇接 类的继承-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'
至此,算是搞明白了。在后面的例子中还需要再慢慢消化。