Python自学之乐-多继承顺序问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python自学之乐-多继承顺序问题相关的知识,希望对你有一定的参考价值。

最近自学Python到面向对象这里,感觉有必要把多继承这里好好理解一下,下面是我自己的一点小总结,如果有朋友觉得有什么不足的,还望不吝赐教!

1、
#Author:clark

class Animal(object):#动物类
#kind = ""
def __init__(self,name,age,food):
self.Name = name
self.Age = age
self.food = food
def eat(self):
print("%s is eat %s" %(self.Name,self.food))
def barking(self):
print("%s is barking"%self.Name)
class Relation(object):#动物关系类
def makefrined(self,obj):
print("%s is making friend with %s"%(self.Name,obj.Name))

class dog(Relation,Animal):#狗继承关系类与动物类
def __init__(self,name,age,food,kind):
super(dog,self).__init__(name,age,food)
self.kind = kind
def barking(self):
print("the barking of %s is wangwangwang!"%self.Name)
class cat(Animal):
def __init__(self,name,age,food,kind):
super(cat,self).__init__(name,age,food)
self.kind = kind
def barking(self):
print("the barking of %s is miaomiaomiao"%self.Name)

dog_teddy = dog("ahuang",3,"bone","teddy")
cat_xiaohua = cat("xiaohua",2,"fish","cat")
dog_teddy.makefrined(cat_xiaohua)
运行结果为:
ahuang is making friend with xiaohua
一开始的疑惑在于,为什么类Relation的makefriend方法的,obj.name从哪来,怎么就运行成功了呢?
后来发现Python的类继承的时候,有一个顺序:优先执行的是自己的构造方法,这里dog类有自己的构造方法,并且定义并继承了Animal类的name等属性,所以才会执行成功;
后来我又想了想,如果把dog类自己的构造方法去掉呢?show me the code
2、
#Author:clark
class Animal(object):#动物类
#kind = ""
def __init__(self,name,age,food):
self.Name = name
self.Age = age
self.food = food
def eat(self):
print("%s is eat %s" %(self.Name,self.food))
def barking(self):
print("%s is barking"%self.Name)
class Relation(object):#动物关系类
def makefrined(self,obj):
print("%s is making friend with %s"%(self.Name,obj.Name))

class dog(Relation,Animal):#狗继承关系类与动物类
# def __init__(self,name,age,food):
# super(dog,self).__init__(name,age,food)
# self.kind = kind
def barking(self):
print("the barking of %s is wangwangwang!"%self.Name)
class cat(Animal):
def __init__(self,name,age,food,kind):
super(cat,self).__init__(name,age,food)
self.kind = kind
def barking(self):
print("the barking of %s is miaomiaomiao"%self.Name)

dog_teddy = dog("ahuang",3,"bone")
cat_xiaohua = cat("xiaohua",2,"fish","cat")
dog_teddy.makefrined(cat_xiaohua)
运行结果为:
ahuang is making friend with xiaohua
啊?为什么呢?明明dog没有构造方法了,按理说dog的实例对象去执行makefriend方法,发现类Relation没有name的属性,应该会抛错才对啊?
才发现Python的类在继承的时候是去找构造方法的,这里dog没有构造方法,Relation也没有,那就找Animal的,发现有,就理所当然的执行成功了!
其实大家可能知道python3类的继承顺序有一个从左往右的原则的,这里如果dog类的继承顺序写成dog(Animal,Relation),可能会觉得好理解一点,其实从左往右是正确的,原则是找到构造
方法就不再往下找,可以验证一下,show me the code
3、
#Author:clark
class Animal(object):#动物类
#kind = ""
def __init__(self,name,age,food):
self.Name = name
self.Age = age
self.food = food
def eat(self):
print("%s is eat %s" %(self.Name,self.food))
def barking(self):
print("%s is barking"%self.Name)
class Relation(object):#动物关系类
def __init__(self):#给Relation写一个构造方法
pass
def makefrined(self,obj):
print("%s is making friend with %s"%(self.Name,obj.Name))

class dog(Relation,Animal):#这里的顺序注意了,两个的类的不同顺序是有区别的
# def __init__(self,name,age,food):
# super(dog,self).__init__(name,age,food)
# self.kind = kind
def barking(self):
print("the barking of %s is wangwangwang!"%self.Name)
class cat(Animal):
def __init__(self,name,age,food,kind):
super(cat,self).__init__(name,age,food)
self.kind = kind
def barking(self):
print("the barking of %s is miaomiaomiao"%self.Name)

dog_teddy = dog("ahuang",3,"bone")
cat_xiaohua = cat("xiaohua",2,"fish","cat")
dog_teddy.makefrined(cat_xiaohua)
运行结果为报错:
TypeError: __init__() takes 1 positional argument but 4 were given
因为首先找到Relation的构造方法,发现没有属性,就不再往下找了,直接报错!可以试一下Animal写在前,就不会报错。

综合以上1、2、3我用自己的语言组织了下总结(供参考吐槽):
简单点就是Python的多继承有一个顺序,自己的构造方法 > 第一个类的构造方法 >大于第二个类的构造方法,以此类推,找到第一个构造方法为止,不再往下去找!!










































































































































以上是关于Python自学之乐-多继承顺序问题的主要内容,如果未能解决你的问题,请参考以下文章

Python自学之乐-装饰器浅谈

Python自学之乐-python 2python 3中经典类新式类的深度和广度优先小结

Python高级语法-多继承MRO相关-多继承顺序(4.5.1)

Python菱形继承的初始化问题和继承顺序

多继承及魔术方法介绍

自学python