python子類繼承父類屬性,Python OOP:繼承、單繼承、多繼承、__mro__、子類重寫父類同名屬性和方法、子類調用父類同名屬性和方法、多層繼承、su

 2023-09-30 阅读 29 评论 0

摘要:一、繼承 Python?向對象的繼承指的是多個類之間的所屬關系,即?類默認繼承?類的所有屬性和?法。 繼承作用:繼承可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。 在Python中,所有類默認繼承object類,object

一、繼承

Python?向對象的繼承指的是多個類之間的所屬關系,即?類默認繼承?類的所有屬性和?法

繼承作用:繼承可以使用現有類的所有功能,并在無需重新編寫原來的類的情況下對這些功能進行擴展。
在這里插入圖片描述
在Python中,所有類默認繼承object類,object類是頂級類或基類;其他?類叫做派?類。

class Being:  # 定義一個類Beingdef __init__(self):  #初始化實例屬性self.num = 1  #在類里面添加實例屬性self.屬性名=值def info_print(self):  # 定義一個實例方法print(self.num)  # 在類里面訪問實例屬性self.屬性名class People(Being):  # 定義一個類People,繼承Being類passp1 = People()  # 創建People類的一個對象p1
p1.info_print()  # 對象調用父類實例方法
p1.num  # 對象訪問父類實例屬性輸出:1
class Being(object):def __init__(self):self.num = 1def info_print(self):print(self.num)class People(Being):passp1 = People()
p1.info_print()輸出:1

二、單繼承

單繼承:一個子類繼承一個父類
在這里插入圖片描述

class Master:def __init__(self):self.kongfu = "古法配方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master):passdaqiu = prentice()
print(daqiu.kongfu)
daqiu.make_cake()輸出:
古法配方
古法配方制作煎餅果子

二、多繼承

python子類繼承父類屬性,多繼承:一個子類同時繼承多個?類
當?個類有多個父類的時候,默認使用第?個父類的同名屬性和方法。
在這里插入圖片描述

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):passdaqiu = prentice()
print(daqiu.kongfu)  # 同名屬性,訪問第一個父類的同名屬性
daqiu.make_cake()  # 同名方法,訪問第一個父類的同名方法print(daqiu.age)  # 不同名屬性,第一個父類正常
print(daqiu.name)  # 不同名屬性,非第一個父類報錯

輸出:
在這里插入圖片描述

三、子類重寫父類同名方法和屬性

?類和父類具有同名屬性和方法,默認使用子類的同名屬性和方法。
在這里插入圖片描述

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))daqiu = prentice()
print(daqiu.kongfu)  # 同名屬性,重寫父類
daqiu.make_cake()  # 同名方法,重寫父類
#如果子類和父類有同名屬性和方法,子類創建對象調用屬性和方法,調用的是子類里面的同名屬性和方法# print(daqiu.age)  # 不同名屬性,報錯
print(daqiu.name)  # 不同名屬性,報錯

輸出:
在這里插入圖片描述

四、___mro___

python多重繼承順序?Python的MRO即Method Resolution Order(方法解析順序),即在調用方法時,會對當前類以及所有的基類進行一個搜索,以確定該方法之所在,而這個搜索的順序就是MRO。

類名.__mro__,返回一個元組。

可以清晰地看到類的層級關系。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))print(prentice.__mro__)
print(type(prentice.__mro__))
print(list(prentice.__mro__))輸出:
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)
<class 'tuple'>
[<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>]

五、子類調用父類的同名屬性和方法

子類里如果有與父類同名的屬性方法,調用這個屬性方法,調用的是子類里面的,調用不到父類里面的屬性方法。

python GIL。如何實現同名屬性方法,既能調用子類里面的,也能調用父類里面的呢?

  • 1.在子類里定義一個函數
  • 2.再次初始化父類屬性(參數self)
  • 3.調用父類方法(參數self)
    在這里插入圖片描述
class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))def make_master_cake(self):  # 調用父類方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
print(daqiu.kongfu)
daqiu.make_cake()
daqiu.make_master_cake()
daqiu.make_school_cake()print(prentice.__mro__)輸出:
獨創配方  # 返回的是子類屬性
獨創配方制作煎餅果子  # 調用的是子類方法
古法配方制作煎餅果子  # 調用到了父類Master的方法
學校技術制作煎餅果子  # 調用到了父類School的方法
(<class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))def make_master_cake(self):  # 調用父類方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_master_cake()
daqiu.make_school_cake()
print(daqiu.kongfu)
daqiu.make_cake()
print(prentice.__mro__)輸出:
古法配方制作煎餅果子
學校技術制作煎餅果子
學校技術  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性
學校技術制作煎餅果子  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性
(<class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)

代碼修正,

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))def make_master_cake(self):  # 調用父類同名屬性方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)Master.__init__(self)  # 父類類名.__init__(self),父類初始化調用一次,注意不要漏寫selfMaster.make_cake(self)  # 父類類名.函數(self), 父類方法調用一次,注意不要漏寫selfdef make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_master_cake()
daqiu.make_school_cake()
print(daqiu.kongfu)
daqiu.make_cake()輸出:
古法配方制作煎餅果子
學校技術制作煎餅果子
學校技術  # 因為先調用父類,這里子類同名屬性仍然被父類屬性覆蓋
獨創配方制作煎餅果子

六、多層繼承

在這里插入圖片描述
多層繼承:大于兩層的繼承

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(Master, School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))def make_master_cake(self):  # 調用父類同名屬性方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)Master.__init__(self)  # 父類初始化調用一次,注意不要漏寫selfMaster.make_cake(self)  # 父類方法調用一次,注意不要漏寫selfdef make_school_cake(self):School.__init__(self)School.make_cake(self)class TuShun(prentice):passxiaoqiu = TuShun()  # 說明子類可以繼承父類所有屬性和方法
xiaoqiu.make_cake()  # 調用父類prentice方法
xiaoqiu.make_master_cake()  # 調用父類prentice的父類方法
xiaoqiu.make_school_cake()  # 調用父類prentice的父類方法
print(xiaoqiu.make_cake)  # 前一步調用父類prentice的父類school類,school類初始化后,屬性是school類的屬性輸出:
獨創配方制作煎餅果子
古法配方制作煎餅果子
學校技術制作煎餅果子
print(TuShun.__mro__)輸出:
(<class '__main__.TuShun'>, <class '__main__.prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)

七、super()調用父類方法

方法一:在子類里定義一個函數,在里面初始化父類屬性、調用父類方法
?法?特點:代碼冗余;?類類名如果變化,這?代碼需要頻繁修改。如果有多個父類,代碼量重復增加。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))# def make_master_cake(self):  # 調用父類同名屬性方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)#     Master.__init__(self)  # 父類初始化調用一次,注意不要漏寫self#     Master.make_cake(self)  # 父類方法調用一次,注意不要漏寫self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ?法?:代碼冗余;?類類名如果變化,這?代碼需要頻繁修改def make_old_cake(self):Master.__init__(self)Master.make_cake(self)School.__init__(self)School.make_cake(self)daqiu = prentice()
daqiu.make_old_cake()  # 從輸出可以看到,兩個父類的同名方法都調用到了
daqiu.make_cake()
print(prentice.__mro__)輸出:
古法配方制作煎餅果子
學校技術制作煎餅果子
獨創配方制作煎餅果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

python3super用法?方法二:super()方法,帶參數寫法, super(當前類名, self).函數()
方法二特點:super里的類名是當前類名,自己可以控制,防止改了類名而未改super里的類名。缺點是仍然需要注意上下保持一致,而且如果有多個父類,需要在多個父類里加入super代碼。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))# 方法二(一):super(當前類名,self).函數()super(School, self).__init__()super(School, self).make_cake()class prentice(School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))# def make_master_cake(self):  # 調用父類同名屬性方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)#     Master.__init__(self)  # 父類初始化調用一次,注意不要漏寫self#     Master.make_cake(self)  # 父類方法調用一次,注意不要漏寫self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ?法?:代碼冗余;?類類名如果變化,這?代碼需要頻繁修改# def make_old_cake(self):#     Master.__init__(self)#     Master.make_cake(self)#     School.__init__(self)#     School.make_cake(self)# 方法二(一):super(當前類名,self).函數()def make_old_cake(self):  # 需要同時在當前類prentice的父類School里也加super()super(prentice, self).__init__()super(prentice, self).make_cake()daqiu = prentice()
daqiu.make_old_cake()
daqiu.make_cake()
print(prentice.__mro__)輸出:
學校技術制作煎餅果子
古法配方制作煎餅果子
獨創配方制作煎餅果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

<推薦使用以下方法>
方法三:super()方法,無參數寫法, super().函數()
方法三特點:super()無參數寫法,自動查找直接父類
使?super() 可以?動查找?類。調?順序遵循 mro 類屬性的順序。?較適合單繼承使?。
.

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School(Master):def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))# 方法二(一):super(當前類名,self).函數()#     super(School, self).__init__()#     super(School, self).make_cake()# 方法二(二):super(當前類名,self).函數()super().__init__()super().make_cake()class prentice(School):def __init__(self):self.kongfu = "獨創配方"def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))# def make_master_cake(self):  # 調用父類同名屬性方法,為保證調用到的也是父類的屬性,必須在調用方法前調用父類的初始化,類名.__init__(self)#     Master.__init__(self)  # 父類初始化調用一次,注意不要漏寫self#     Master.make_cake(self)  # 父類方法調用一次,注意不要漏寫self## def make_school_cake(self):#     School.__init__(self)#     School.make_cake(self)# ?法?:代碼冗余;?類類名如果變化,這?代碼需要頻繁修改# def make_old_cake(self):#     Master.__init__(self)#     Master.make_cake(self)#     School.__init__(self)#     School.make_cake(self)# 方法二(一):super(當前類名,self).函數()# def make_old_cake(self):  # 需要同時在當前類prentice的父類School里也加super()#     super(prentice, self).__init__()#     super(prentice, self).make_cake()# 方法二(二):super(當前類名,self).函數()def make_old_cake(self):super().__init__()super().make_cake()daqiu = prentice()
daqiu.make_old_cake()
daqiu.make_cake()
print(prentice.__mro__)輸出:
學校技術制作煎餅果子
古法配方制作煎餅果子
獨創配方制作煎餅果子
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

八、定義私有(實例)屬性和方法

默認情況下,只要繼承關系建立,子類默認繼承父類所有的屬性和方法,這些能夠繼承給子類的屬性方法叫共有權限。

如果有些屬性和方法不想繼承給子類了,私有權限,可以添加私有屬性方法來實現。
在這里插入圖片描述
注意:私有屬性和私有方法只能在類里面訪問和修改。,對某些屬性方法起到保護作用。

python拋出異常?.

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(School, Master):def __init__(self):self.kongfu = "獨創配方"self.__money = "一個億"  # 定義私有屬性def __printinfo(self):  # 定義私有?法print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))class TuShun(prentice):passxiaoqiu = TuShun()
print(xiaoqiu.kongfu)  # 獨創配方
print(xiaoqiu.money)  # AttributeError: 'TuShun' object has no attribute 'money'
print(xiaoqiu.__money)  # AttributeError: 'TuShun' object has no attribute '__money'
xiaoqiu.printinfo  # AttributeError: 'TuShun' object has no attribute 'printinfo'
xiaoqiu.__printinfo  # AttributeError: 'TuShun' object has no attribute '__printinfo'
# ?類?法繼承?類的私有屬性和私有?法

九、獲取和修改私有屬性值

在Python中,在類里面,定義函數 get_屬性名 ?來獲取私有屬性,定義 set_屬性名 ?來修改私有屬性值。

class Master:def __init__(self):self.kongfu = "古法配方"self.age = 100def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class School:def __init__(self):self.kongfu = "學校技術"self.name = "新東方"def make_cake(self):print("{}制作煎餅果子".format(self.kongfu))class prentice(School, Master):def __init__(self):self.kongfu = "獨創配方"self.__money = "私有:一個億"def get_money(self):print(self.__money)  # 或者這里用 return self.__money,調用時用printdef set_money(self):self.__money = "私有更新:十個億"def __printinfo(self):print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()  # 如果先調用了父類的屬性和方法,父類屬性會覆蓋子類屬性,故在調用子類方法前,先調用子類自己的初始化print("{}制作煎餅果子".format(self.kongfu))class TuShun(prentice):passxiaoqiu = TuShun()
xiaoqiu.get_money()
xiaoqiu.set_money()
xiaoqiu.get_money()print(prentice.__mro__)輸出:
私有:一個億
私有更新:十個億
(<class '__main__.prentice'>, <class '__main__.School'>, <class '__main__.Master'>, <class 'object'>)

十、私有類屬性

class Dog:__age = 3@classmethoddef get_age(cls):return cls.__agewangcai = Dog()
result = wangcai.get_age()
print(result)  # 3

十一、繼承知識小結

在這里插入圖片描述
PS: source,itheima

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/106437.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息