1. 程式人生 > >Python自學之樂-多繼承順序問題

Python自學之樂-多繼承順序問題

一個 才會 error osi 感覺 int 實例對象 學python ted

最近自學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自學之樂-多繼承順序問題