Python学习之路(四)——Python核心编程3(面向对象、模块_包_异常)
面向?qū)ο蠡A(chǔ)
一. 理解面向?qū)ο?/h2>
面向?qū)ο笫且环N抽象化的編程思想,很多編程語(yǔ)言中都有的一種思想。
例如:洗衣服
思考:幾種途徑可以完成洗衣服?
答: 手洗 和 機(jī)洗。
手洗:找盆 - 放水 - 加洗衣粉 - 浸泡 - 搓洗 - 擰干水 - 倒水 - 漂洗N次 - 擰干 - 晾曬。
機(jī)洗:打開(kāi)洗衣機(jī) - 放衣服 - 加洗衣粉 - 按下開(kāi)始按鈕 - 晾曬。
思考:對(duì)比兩種洗衣服途徑,同學(xué)們發(fā)現(xiàn)了什么?
答:機(jī)洗更簡(jiǎn)單
思考:機(jī)洗,只需要找到一臺(tái)洗衣機(jī),加入簡(jiǎn)單操作就可以完成洗衣服的工作,而不需要關(guān)心洗衣機(jī)內(nèi)部發(fā)生了什么事情。
總結(jié):面向?qū)ο缶褪菍⒕幊坍?dāng)成是一個(gè)事物,對(duì)外界來(lái)說(shuō),事物是直接使用的,不用去管他內(nèi)部的情況。而編程就是設(shè)置事物能夠做什么事。
二. 類和對(duì)象
思考:洗衣機(jī)洗衣服描述過(guò)程中,洗衣機(jī)其實(shí)就是一個(gè)事物,即對(duì)象,洗衣機(jī)對(duì)象哪來(lái)的呢?
答:洗衣機(jī)是由工廠工人制作出來(lái)。
思考:工廠工人怎么制作出的洗衣機(jī)?
答:工人根據(jù)設(shè)計(jì)師設(shè)計(jì)的功能圖紙制作洗衣機(jī)。
總結(jié):圖紙 → 洗衣機(jī) → 洗衣服。
在面向?qū)ο缶幊踢^(guò)程中,有兩個(gè)重要組成部分:類 和 對(duì)象。
類和對(duì)象的關(guān)系:用類去創(chuàng)建一個(gè)對(duì)象。
2.1 理解類和對(duì)象
2.1.1 類
類是對(duì)一系列具有相同特征和行為的事物的統(tǒng)稱,是一個(gè)抽象的概念,不是真實(shí)存在的事物。
- 特征即是屬性
- 行為即是方法
類比如是制造洗衣機(jī)時(shí)要用到的圖紙,也就是說(shuō)類是用來(lái)創(chuàng)建對(duì)象。
2.1.2 對(duì)象
對(duì)象是類創(chuàng)建出來(lái)的真實(shí)存在的事物,例如:洗衣機(jī)。
注意:開(kāi)發(fā)中,先有類,再有對(duì)象。
2.2 面向?qū)ο髮?shí)現(xiàn)方法
2.2.1 定義類
Python2中類分為:經(jīng)典類 和 新式類
- 語(yǔ)法
注意:類名要滿足標(biāo)識(shí)符命名規(guī)則,同時(shí)遵循大駝峰命名習(xí)慣。
- 體驗(yàn)
- 拓展:經(jīng)典類
不由任意內(nèi)置類型派生出的類,稱之為經(jīng)典類
class 類名:代碼......2.2.2 創(chuàng)建對(duì)象
對(duì)象又名實(shí)例。
- 語(yǔ)法
- 體驗(yàn)
注意:創(chuàng)建對(duì)象的過(guò)程也叫實(shí)例化對(duì)象。
2.2.3 self
self指的是調(diào)用該函數(shù)的對(duì)象。
# 1. 定義類 class Washer():def wash(self):print('我會(huì)洗衣服')# <__main__.Washer object at 0x0000024BA2B34240>print(self)# 2. 創(chuàng)建對(duì)象 haier1 = Washer() # <__main__.Washer object at 0x0000018B7B224240> print(haier1) # haier1對(duì)象調(diào)用實(shí)例方法 haier1.wash()haier2 = Washer() # <__main__.Washer object at 0x0000022005857EF0> print(haier2)注意:打印對(duì)象和self得到的結(jié)果是一致的,都是當(dāng)前對(duì)象的內(nèi)存中存儲(chǔ)地址。
三. 添加和獲取對(duì)象屬性
屬性即是特征,比如:洗衣機(jī)的寬度、高度、重量…
對(duì)象屬性既可以在類外面添加和獲取,也能在類里面添加和獲取。
3.1 類外面添加對(duì)象屬性
- 語(yǔ)法
- 體驗(yàn)
3.2 類外面獲取對(duì)象屬性
- 語(yǔ)法
- 體驗(yàn)
3.3 類里面獲取對(duì)象屬性
- 語(yǔ)法
- 體驗(yàn)
四. 魔法方法
在Python中,__xx__()的函數(shù)叫做魔法方法,指的是具有特殊功能的函數(shù)。
4.1 __init__()
4.1.1 體驗(yàn)__init__()
思考:洗衣機(jī)的寬度高度是與生俱來(lái)的屬性,可不可以在生產(chǎn)過(guò)程中就賦予這些屬性呢?
答:理應(yīng)如此。
__init__()方法的作用:初始化對(duì)象。
class Washer():# 定義初始化功能的函數(shù)def __init__(self):# 添加實(shí)例屬性self.width = 500self.height = 800def print_info(self):# 類里面調(diào)用實(shí)例屬性print(f'洗衣機(jī)的寬度是{self.width}, 高度是{self.height}')haier1 = Washer() haier1.print_info()注意:
- __init__()方法,在創(chuàng)建一個(gè)對(duì)象時(shí)默認(rèn)被調(diào)用,不需要手動(dòng)調(diào)用
- __init__(self)中的self參數(shù),不需要開(kāi)發(fā)者傳遞,python解釋器會(huì)自動(dòng)把當(dāng)前的對(duì)象引用傳遞過(guò)去。
4.1.2 帶參數(shù)的__init__()
思考:一個(gè)類可以創(chuàng)建多個(gè)對(duì)象,如何對(duì)不同的對(duì)象設(shè)置不同的初始化屬性呢?
答:傳參數(shù)。
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef print_info(self):print(f'洗衣機(jī)的寬度是{self.width}')print(f'洗衣機(jī)的高度是{self.height}')haier1 = Washer(10, 20) haier1.print_info()haier2 = Washer(30, 40) haier2.print_info()4.2 __str__()
當(dāng)使用print輸出對(duì)象的時(shí)候,默認(rèn)打印對(duì)象的內(nèi)存地址。如果類定義了__str__方法,那么就會(huì)打印從在這個(gè)方法中 return 的數(shù)據(jù)。
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef __str__(self):return '這是海爾洗衣機(jī)的說(shuō)明書(shū)'haier1 = Washer(10, 20) # 這是海爾洗衣機(jī)的說(shuō)明書(shū) print(haier1)4.3 __del__()
當(dāng)刪除對(duì)象時(shí),python解釋器也會(huì)默認(rèn)調(diào)用__del__()方法。
class Washer():def __init__(self, width, height):self.width = widthself.height = heightdef __del__(self):print(f'{self}對(duì)象已經(jīng)被刪除')haier1 = Washer(10, 20)# <__main__.Washer object at 0x0000026118223278>對(duì)象已經(jīng)被刪除 del haier1五. 綜合應(yīng)用
5.1 烤地瓜
5.1.1 需求
需求主線:
被烤的時(shí)間和對(duì)應(yīng)的地瓜狀態(tài):
0-3分鐘:生的
3-5分鐘:半生不熟
5-8分鐘:熟的
超過(guò)8分鐘:烤糊了
添加的調(diào)料:
用戶可以按自己的意愿添加調(diào)料
5.1.2 步驟分析
需求涉及一個(gè)事物: 地瓜,故案例涉及一個(gè)類:地瓜類。
5.1.2.1 定義類
-
地瓜的屬性
- 被烤的時(shí)間
- 地瓜的狀態(tài)
- 添加的調(diào)料
-
地瓜的方法
- 被烤
- 用戶根據(jù)意愿設(shè)定每次烤地瓜的時(shí)間
- 判斷地瓜被烤的總時(shí)間是在哪個(gè)區(qū)間,修改地瓜狀態(tài)
- 添加調(diào)料
- 用戶根據(jù)意愿設(shè)定添加的調(diào)料
- 將用戶添加的調(diào)料存儲(chǔ)
- 被烤
-
顯示對(duì)象信息
5.1.2.2 創(chuàng)建對(duì)象,調(diào)用相關(guān)實(shí)例方法
5.1.3 代碼實(shí)現(xiàn)
5.1.3.1 定義類
- 地瓜屬性
- 定義地瓜初始化屬性,后期根據(jù)程序推進(jìn)更新實(shí)例屬性
5.1.3.2 定義烤地瓜方法
class SweetPotato():......def cook(self, time):"""烤地瓜的方法"""self.cook_time += timeif 0 <= self.cook_time < 3:self.cook_static = '生的'elif 3 <= self.cook_time < 5:self.cook_static = '半生不熟'elif 5 <= self.cook_time < 8:self.cook_static = '熟了'elif self.cook_time >= 8:self.cook_static = '烤糊了'5.1.3.3 書(shū)寫(xiě)str魔法方法,用于輸出對(duì)象狀態(tài)
class SweetPotato():......def __str__(self):return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}'5.1.3.4 創(chuàng)建對(duì)象,測(cè)試實(shí)例屬性和實(shí)例方法
digua1 = SweetPotato() print(digua1) digua1.cook(2) print(digua1)5.1.3.5 定義添加調(diào)料方法,并調(diào)用該實(shí)例方法
class SweetPotato():......def add_condiments(self, condiment):"""添加調(diào)料"""self.condiments.append(condiment)def __str__(self):return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}, 添加的調(diào)料有{self.condiments}'digua1 = SweetPotato() print(digua1)digua1.cook(2) digua1.add_condiments('醬油') print(digua1)digua1.cook(2) digua1.add_condiments('辣椒面兒') print(digua1)digua1.cook(2) print(digua1)digua1.cook(2) print(digua1)5.1.4 代碼總覽
# 定義類 class SweetPotato():def __init__(self):# 被烤的時(shí)間self.cook_time = 0# 地瓜的狀態(tài)self.cook_static = '生的'# 調(diào)料列表self.condiments = []def cook(self, time):"""烤地瓜的方法"""self.cook_time += timeif 0 <= self.cook_time < 3:self.cook_static = '生的'elif 3 <= self.cook_time < 5:self.cook_static = '半生不熟'elif 5 <= self.cook_time < 8:self.cook_static = '熟了'elif self.cook_time >= 8:self.cook_static = '烤糊了'def add_condiments(self, condiment):"""添加調(diào)料"""self.condiments.append(condiment)def __str__(self):return f'這個(gè)地瓜烤了{(lán)self.cook_time}分鐘, 狀態(tài)是{self.cook_static}, 添加的調(diào)料有{self.condiments}'digua1 = SweetPotato() print(digua1)digua1.cook(2) digua1.add_condiments('醬油') print(digua1)digua1.cook(2) digua1.add_condiments('辣椒面兒') print(digua1)digua1.cook(2) print(digua1)digua1.cook(2) print(digua1)5.2 搬家具
5.2.1 需求
將小于房子剩余面積的家具擺放到房子中
5.2.2 步驟分析
需求涉及兩個(gè)事物:房子 和 家具,故被案例涉及兩個(gè)類:房子類 和 家具類。
5.2.2.1 定義類
-
房子類
- 實(shí)例屬性
- 房子地理位置
- 房子占地面積
- 房子剩余面積
- 房子內(nèi)家具列表
- 實(shí)例方法
- 容納家具
- 顯示房屋信息
- 實(shí)例屬性
-
家具類
- 家具名稱
- 家具占地面積
5.2.2.2 創(chuàng)建對(duì)象并調(diào)用相關(guān)方法
5.2.3 代碼實(shí)現(xiàn)
5.2.3.1 定義類
- 家具類
-
房子類
5.2.3.2 創(chuàng)建對(duì)象并調(diào)用實(shí)例屬性和方法
bed = Furniture('雙人床', 6) jia1 = Home('北京', 1200) print(jia1)jia1.add_furniture(bed) print(jia1)sofa = Furniture('沙發(fā)', 10) jia1.add_furniture(sofa) print(jia1)ball = Furniture('籃球場(chǎng)', 1500) jia1.add_furniture(ball) print(jia1)面向?qū)ο?繼承
一. 繼承的概念
生活中的繼承,一般指的是子女繼承父輩的財(cái)產(chǎn)。
- 拓展1:經(jīng)典類或舊式類
不由任意內(nèi)置類型派生出的類,稱之為經(jīng)典類。
class 類名:代碼......- 拓展2:新式類
Python面向?qū)ο蟮睦^承指的是多個(gè)類之間的所屬關(guān)系,即子類默認(rèn)繼承父類的所有屬性和方法,具體如下:
# 父類A class A(object):def __init__(self):self.num = 1def info_print(self):print(self.num)# 子類B class B(A):passresult = B() result.info_print() # 1在Python中,所有類默認(rèn)繼承object類,object類是頂級(jí)類或基類;其他子類叫做派生類。
二. 單繼承
故事主線:一個(gè)煎餅果子老師傅,在煎餅果子界摸爬滾打多年,研發(fā)了一套精湛的攤煎餅果子的技術(shù)。師父要把這套技術(shù)傳授給他的唯一的最得意的徒弟。
分析:徒弟是不是要繼承師父的所有技術(shù)?
# 1. 師父類 class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 2. 徒弟類 class Prentice(Master):pass# 3. 創(chuàng)建對(duì)象daqiu daqiu = Prentice() # 4. 對(duì)象訪問(wèn)實(shí)例屬性 print(daqiu.kongfu) # 5. 對(duì)象調(diào)用實(shí)例方法 daqiu.make_cake()三. 多繼承
故事推進(jìn):daqiu是個(gè)愛(ài)學(xué)習(xí)的好孩子,想學(xué)習(xí)更多的煎餅果子技術(shù),于是,在百度搜索到黑馬程序員,報(bào)班學(xué)習(xí)煎餅果子技術(shù)。
所謂多繼承意思就是一個(gè)類同時(shí)繼承了多個(gè)父類。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 創(chuàng)建學(xué)校類 class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class Prentice(School, Master):passdaqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake()注意:當(dāng)一個(gè)類有多個(gè)父類的時(shí)候,默認(rèn)使用第一個(gè)父類的同名屬性和方法。
四. 子類重寫(xiě)父類同名方法和屬性
故事:daqiu掌握了師父和培訓(xùn)的技術(shù)后,自己潛心鉆研出自己的獨(dú)門配方的一套全新的煎餅果子技術(shù)。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 獨(dú)創(chuàng)配方 class Prentice(School, Master):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')daqiu = Prentice() print(daqiu.kongfu) daqiu.make_cake()print(Prentice.__mro__)子類和父類具有同名屬性和方法,默認(rèn)使用子類的同名屬性和方法。
五. 子類調(diào)用父類的同名方法和屬性
故事:很多顧客都希望也能吃到古法和黑馬的技術(shù)的煎餅果子。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class Prentice(School, Master):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'def make_cake(self):# 如果是先調(diào)用了父類的屬性和方法,父類屬性會(huì)覆蓋子類屬性,故在調(diào)用屬性前,先調(diào)用自己子類的初始化self.__init__()print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 調(diào)用父類方法,但是為保證調(diào)用到的也是父類的屬性,必須在調(diào)用方法前調(diào)用父類的初始化def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)daqiu = Prentice()daqiu.make_cake()daqiu.make_master_cake()daqiu.make_school_cake()daqiu.make_cake()六. 多層繼承
故事:N年后,daqiu老了,想要把所有技術(shù)傳承給自己的徒弟。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class Prentice(School, Master):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'def make_cake(self):self.__init__()print(f'運(yùn)用{self.kongfu}制作煎餅果子')def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)# 徒孫類 class Tusun(Prentice):passxiaoqiu = Tusun()xiaoqiu.make_cake()xiaoqiu.make_school_cake()xiaoqiu.make_master_cake()七. super()調(diào)用父類方法
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(Master):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 方法2.1# super(School, self).__init__()# super(School, self).make_cake()# 方法2.2super().__init__()super().make_cake()class Prentice(School):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子技術(shù)]'def make_cake(self):self.__init__()print(f'運(yùn)用{self.kongfu}制作煎餅果子')# 子類調(diào)用父類的同名方法和屬性:把父類的同名屬性和方法再次封裝def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)# 一次性調(diào)用父類的同名屬性和方法def make_old_cake(self):# 方法一:代碼冗余;父類類名如果變化,這里代碼需要頻繁修改# Master.__init__(self)# Master.make_cake(self)# School.__init__(self)# School.make_cake(self)# 方法二: super()# 方法2.1 super(當(dāng)前類名, self).函數(shù)()# super(Prentice, self).__init__()# super(Prentice, self).make_cake()# 方法2.2 super().函數(shù)()super().__init__()super().make_cake()daqiu = Prentice()daqiu.make_old_cake()注意:使用super() 可以自動(dòng)查找父類。調(diào)用順序遵循 __mro__ 類屬性的順序。比較適合單繼承使用。
八. 私有權(quán)限
8.1 定義私有屬性和方法
在Python中,可以為實(shí)例屬性和方法設(shè)置私有權(quán)限,即設(shè)置某個(gè)實(shí)例屬性或?qū)嵗椒ú焕^承給子類。
故事:daqiu把技術(shù)傳承給徒弟的同時(shí),不想把自己的錢(2000000個(gè)億)繼承給徒弟,這個(gè)時(shí)候就要為錢這個(gè)實(shí)例屬性設(shè)置私有權(quán)限。
設(shè)置私有權(quán)限的方法:在屬性名和方法名 前面 加上兩個(gè)下劃線 __。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class Prentice(School, Master):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'# 定義私有屬性self.__money = 2000000# 定義私有方法def __info_print(self):print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()print(f'運(yùn)用{self.kongfu}制作煎餅果子')def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)# 徒孫類 class Tusun(Prentice):passdaqiu = Prentice() # 對(duì)象不能訪問(wèn)私有屬性和私有方法 # print(daqiu.__money) # daqiu.__info_print()xiaoqiu = Tusun() # 子類無(wú)法繼承父類的私有屬性和私有方法 # print(xiaoqiu.__money) # 無(wú)法訪問(wèn)實(shí)例屬性__money # xiaoqiu.__info_print()注意:私有屬性和私有方法只能在類里面訪問(wèn)和修改。
8.2 獲取和修改私有屬性值
在Python中,一般定義函數(shù)名get_xx用來(lái)獲取私有屬性,定義set_xx用來(lái)修改私有屬性值。
class Master(object):def __init__(self):self.kongfu = '[古法煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class School(object):def __init__(self):self.kongfu = '[黑馬煎餅果子配方]'def make_cake(self):print(f'運(yùn)用{self.kongfu}制作煎餅果子')class Prentice(School, Master):def __init__(self):self.kongfu = '[獨(dú)創(chuàng)煎餅果子配方]'self.__money = 2000000# 獲取私有屬性def get_money(self):return self.__money# 修改私有屬性def set_money(self):self.__money = 500def __info_print(self):print(self.kongfu)print(self.__money)def make_cake(self):self.__init__()print(f'運(yùn)用{self.kongfu}制作煎餅果子')def make_master_cake(self):Master.__init__(self)Master.make_cake(self)def make_school_cake(self):School.__init__(self)School.make_cake(self)# 徒孫類 class Tusun(Prentice):passdaqiu = Prentice()xiaoqiu = Tusun() # 調(diào)用get_money函數(shù)獲取私有屬性money的值 print(xiaoqiu.get_money()) # 調(diào)用set_money函數(shù)修改私有屬性money的值 xiaoqiu.set_money() print(xiaoqiu.get_money())課程:面向?qū)ο?其他
一. 面向?qū)ο笕筇匦?/h2>
- 封裝
- 將屬性和方法書(shū)寫(xiě)到類的里面的操作即為封裝
- 封裝可以為屬性和方法添加私有權(quán)限
- 繼承
- 子類默認(rèn)繼承父類的所有屬性和方法
- 子類可以重寫(xiě)父類屬性和方法
- 多態(tài)
- 傳入不同的對(duì)象,產(chǎn)生不同的結(jié)果
二. 多態(tài)
2.1 了解多態(tài)
- 將屬性和方法書(shū)寫(xiě)到類的里面的操作即為封裝
- 封裝可以為屬性和方法添加私有權(quán)限
- 子類默認(rèn)繼承父類的所有屬性和方法
- 子類可以重寫(xiě)父類屬性和方法
- 傳入不同的對(duì)象,產(chǎn)生不同的結(jié)果
多態(tài)指的是一類事物有多種形態(tài),(一個(gè)抽象類有多個(gè)子類,因而多態(tài)的概念依賴于繼承)。
- 定義:多態(tài)是一種使用對(duì)象的方式,子類重寫(xiě)父類方法,調(diào)用不同子類對(duì)象的相同父類方法,可以產(chǎn)生不同的執(zhí)行結(jié)果
- 好處:調(diào)用靈活,有了多態(tài),更容易編寫(xiě)出通用的代碼,做出通用的編程,以適應(yīng)需求的不斷變化!
- 實(shí)現(xiàn)步驟:
- 定義父類,并提供公共方法
- 定義子類,并重寫(xiě)父類方法
- 傳遞子類對(duì)象給調(diào)用者,可以看到不同子類執(zhí)行效果不同
2.2 體驗(yàn)多態(tài)
class Dog(object):def work(self): # 父類提供統(tǒng)一的方法,哪怕是空方法print('指哪打哪...')class ArmyDog(Dog): # 繼承Dog類def work(self): # 子類重寫(xiě)父類同名方法print('追擊敵人...')class DrugDog(Dog):def work(self):print('追查毒品...')class Person(object):def work_with_dog(self, dog): # 傳入不同的對(duì)象,執(zhí)行不同的代碼,即不同的work函數(shù)dog.work()ad = ArmyDog() dd = DrugDog()daqiu = Person() daqiu.work_with_dog(ad) daqiu.work_with_dog(dd)三. 類屬性和實(shí)例屬性
3.1 類屬性
3.1.1 設(shè)置和訪問(wèn)類屬性
- 類屬性就是 類對(duì)象 所擁有的屬性,它被 該類的所有實(shí)例對(duì)象所共有。
- 類屬性可以使用 類對(duì)象 或 實(shí)例對(duì)象 訪問(wèn)。
類屬性的優(yōu)點(diǎn)
- 記錄的某項(xiàng)數(shù)據(jù) 始終保持一致時(shí),則定義類屬性。
- 實(shí)例屬性 要求 每個(gè)對(duì)象 為其 單獨(dú)開(kāi)辟一份內(nèi)存空間 來(lái)記錄數(shù)據(jù),而 類屬性 為全類所共有 ,僅占用一份內(nèi)存,更加節(jié)省內(nèi)存空間。
3.1.2 修改類屬性
類屬性只能通過(guò)類對(duì)象修改,不能通過(guò)實(shí)例對(duì)象修改,如果通過(guò)實(shí)例對(duì)象修改類屬性,表示的是創(chuàng)建了一個(gè)實(shí)例屬性。
class Dog(object):tooth = 10wangcai = Dog() xiaohei = Dog()# 修改類屬性 Dog.tooth = 12 print(Dog.tooth) # 12 print(wangcai.tooth) # 12 print(xiaohei.tooth) # 12# 不能通過(guò)對(duì)象修改屬性,如果這樣操作,實(shí)則是創(chuàng)建了一個(gè)實(shí)例屬性 wangcai.tooth = 20 print(Dog.tooth) # 12 print(wangcai.tooth) # 20 print(xiaohei.tooth) # 123.2 實(shí)例屬性
class Dog(object):def __init__(self):self.age = 5def info_print(self):print(self.age)wangcai = Dog() print(wangcai.age) # 5 # print(Dog.age) # 報(bào)錯(cuò):實(shí)例屬性不能通過(guò)類訪問(wèn) wangcai.info_print() # 5四. 類方法和靜態(tài)方法
4.1 類方法
4.1.1 類方法特點(diǎn)
- 需要用裝飾器@classmethod來(lái)標(biāo)識(shí)其為類方法,對(duì)于類方法,第一個(gè)參數(shù)必須是類對(duì)象,一般以cls作為第一個(gè)參數(shù)。
4.1.2 類方法使用場(chǎng)景
- 當(dāng)方法中 需要使用類對(duì)象 (如訪問(wèn)私有類屬性等)時(shí),定義類方法
- 類方法一般和類屬性配合使用
4.2 靜態(tài)方法
4.2.1 靜態(tài)方法特點(diǎn)
- 需要通過(guò)裝飾器@staticmethod來(lái)進(jìn)行修飾,靜態(tài)方法既不需要傳遞類對(duì)象也不需要傳遞實(shí)例對(duì)象(形參沒(méi)有self/cls)。
- 靜態(tài)方法 也能夠通過(guò) 實(shí)例對(duì)象 和 類對(duì)象 去訪問(wèn)。
4.2.2 靜態(tài)方法使用場(chǎng)景
- 當(dāng)方法中 既不需要使用實(shí)例對(duì)象(如實(shí)例對(duì)象,實(shí)例屬性),也不需要使用類對(duì)象 (如類屬性、類方法、創(chuàng)建實(shí)例等)時(shí),定義靜態(tài)方法
- 取消不需要的參數(shù)傳遞,有利于 減少不必要的內(nèi)存占用和性能消耗
課程:異常
一. 了解異常
當(dāng)檢測(cè)到一個(gè)錯(cuò)誤時(shí),解釋器就無(wú)法繼續(xù)執(zhí)行了,反而出現(xiàn)了一些錯(cuò)誤的提示,這就是所謂的"異常"。
例如:以r方式打開(kāi)一個(gè)不存在的文件。
open('test.txt', 'r')二. 異常的寫(xiě)法
2.1 語(yǔ)法
try:可能發(fā)生錯(cuò)誤的代碼 except:如果出現(xiàn)異常執(zhí)行的代碼2.2 快速體驗(yàn)
需求:嘗試以r模式打開(kāi)文件,如果文件不存在,則以w方式打開(kāi)。
try:f = open('test.txt', 'r') except:f = open('test.txt', 'w')2.3 捕獲指定異常
2.3.1 語(yǔ)法
try:可能發(fā)生錯(cuò)誤的代碼 except 異常類型:如果捕獲到該異常類型執(zhí)行的代碼2.3.2 體驗(yàn)
try:print(num) except NameError:print('有錯(cuò)誤')注意:
2.3.3 捕獲多個(gè)指定異常
當(dāng)捕獲多個(gè)異常時(shí),可以把要捕獲的異常類型的名字,放到except 后,并使用元組的方式進(jìn)行書(shū)寫(xiě)。
try:print(1/0)except (NameError, ZeroDivisionError):print('有錯(cuò)誤')2.3.4 捕獲異常描述信息
try:print(num) except (NameError, ZeroDivisionError) as result:print(result)2.3.5 捕獲所有異常
Exception是所有程序異常類的父類。
try:print(num) except Exception as result:print(result)2.4 異常的else
else表示的是如果沒(méi)有異常要執(zhí)行的代碼。
try:print(1) except Exception as result:print(result) else:print('我是else,是沒(méi)有異常的時(shí)候執(zhí)行的代碼')2.5 異常的finally
finally表示的是無(wú)論是否異常都要執(zhí)行的代碼,例如關(guān)閉文件。
try:f = open('test.txt', 'r') except Exception as result:f = open('test.txt', 'w') else:print('沒(méi)有異常,真開(kāi)心') finally:f.close()三. 異常的傳遞
體驗(yàn)異常傳遞
需求:
? 1. 嘗試只讀方式打開(kāi)test.txt文件,如果文件存在則讀取文件內(nèi)容,文件不存在則提示用戶即可。
? 2. 讀取內(nèi)容要求:嘗試循環(huán)讀取內(nèi)容,讀取過(guò)程中如果檢測(cè)到用戶意外終止程序,則except捕獲異常并提示用戶。
import time try:f = open('test.txt')try:while True:content = f.readline()if len(content) == 0:breaktime.sleep(2)print(content)except:# 如果在讀取文件的過(guò)程中,產(chǎn)生了異常,那么就會(huì)捕獲到# 比如 按下了 ctrl+cprint('意外終止了讀取數(shù)據(jù)')finally:f.close()print('關(guān)閉文件') except:print("沒(méi)有這個(gè)文件")四. 自定義異常
在Python中,拋出自定義異常的語(yǔ)法為raise 異常類對(duì)象。
需求:密碼長(zhǎng)度不足,則報(bào)異常(用戶輸入密碼,如果輸入的長(zhǎng)度不足3位,則報(bào)錯(cuò),即拋出自定義異常,并捕獲該異常)。
# 自定義異常類,繼承Exception class ShortInputError(Exception):def __init__(self, length, min_len):self.length = lengthself.min_len = min_len# 設(shè)置拋出異常的描述信息def __str__(self):return f'你輸入的長(zhǎng)度是{self.length}, 不能少于{self.min_len}個(gè)字符'def main():try:con = input('請(qǐng)輸入密碼:')if len(con) < 3:raise ShortInputError(len(con), 3)except Exception as result:print(result)else:print('密碼已經(jīng)輸入完成')main()模塊和包
一. 模塊
Python 模塊(Module),是一個(gè) Python 文件,以 .py 結(jié)尾,包含了 Python 對(duì)象定義和Python語(yǔ)句。
模塊能定義函數(shù),類和變量,模塊里也能包含可執(zhí)行的代碼。
1.1. 導(dǎo)入模塊
1.1.1 導(dǎo)入模塊的方式
- import 模塊名
- from 模塊名 import 功能名
- from 模塊名 import *
- import 模塊名 as 別名
- from 模塊名 import 功能名 as 別名
1.1.2 導(dǎo)入方式詳解
1.1.2.1 import
- 語(yǔ)法
- 體驗(yàn)
1.1.2.2 from…import…
- 語(yǔ)法
- 體驗(yàn)
1.1.2.3 from … import *
- 語(yǔ)法
- 體驗(yàn)
1.1.2.4 as定義別名
- 語(yǔ)法
- 體驗(yàn)
1.2. 制作模塊
在Python中,每個(gè)Python文件都可以作為一個(gè)模塊,模塊的名字就是文件的名字。也就是說(shuō)自定義模塊名必須要符合標(biāo)識(shí)符命名規(guī)則。
1.2.1 定義模塊
新建一個(gè)Python文件,命名為my_module1.py,并定義testA函數(shù)。
def testA(a, b):print(a + b)1.2.2 測(cè)試模塊
在實(shí)際開(kāi)中,當(dāng)一個(gè)開(kāi)發(fā)人員編寫(xiě)完一個(gè)模塊后,為了讓模塊能夠在項(xiàng)目中達(dá)到想要的效果,這個(gè)開(kāi)發(fā)人員會(huì)自行在py文件中添加一些測(cè)試信息.,例如,在my_module1.py文件中添加測(cè)試代碼。
def testA(a, b):print(a + b)testA(1, 1)此時(shí),無(wú)論是當(dāng)前文件,還是其他已經(jīng)導(dǎo)入了該模塊的文件,在運(yùn)行的時(shí)候都會(huì)自動(dòng)執(zhí)行testA函數(shù)的調(diào)用。
解決辦法如下:
def testA(a, b):print(a + b)# 只在當(dāng)前文件中調(diào)用該函數(shù),其他導(dǎo)入的文件內(nèi)不符合該條件,則不執(zhí)行testA函數(shù)調(diào)用 if __name__ == '__main__':testA(1, 1)1.2.3 調(diào)用模塊
import my_module1 my_module1.testA(1, 1)1.2.4 注意事項(xiàng)
如果使用from .. import ..或from .. import *導(dǎo)入多個(gè)模塊的時(shí)候,且模塊內(nèi)有同名功能。當(dāng)調(diào)用這個(gè)同名功能的時(shí)候,調(diào)用到的是后面導(dǎo)入的模塊的功能。
- 體驗(yàn)
1.3. 模塊定位順序
當(dāng)導(dǎo)入一個(gè)模塊,Python解析器對(duì)模塊位置的搜索順序是:
模塊搜索路徑存儲(chǔ)在system模塊的sys.path變量中。變量里包含當(dāng)前目錄,PYTHONPATH和由安裝過(guò)程決定的默認(rèn)目錄。
- 注意
- 自己的文件名不要和已有模塊名重復(fù),否則導(dǎo)致模塊功能無(wú)法使用
- 使用from 模塊名 import 功能的時(shí)候,如果功能名字重復(fù),調(diào)用到的是最后定義或?qū)氲墓δ堋?/li>
1.4. __all__
如果一個(gè)模塊文件中有__all__變量,當(dāng)使用from xxx import *導(dǎo)入時(shí),只能導(dǎo)入這個(gè)列表中的元素。
- my_module1模塊代碼
- 導(dǎo)入模塊的文件代碼
二. 包
包將有聯(lián)系的模塊組織在一起,即放到同一個(gè)文件夾下,并且在這個(gè)文件夾創(chuàng)建一個(gè)名字為_(kāi)_init__.py 文件,那么這個(gè)文件夾就稱之為包。
2.1 制作包
[New] — [Python Package] — 輸入包名 — [OK] — 新建功能模塊(有聯(lián)系的模塊)。
注意:新建包后,包內(nèi)部會(huì)自動(dòng)創(chuàng)建__init__.py文件,這個(gè)文件控制著包的導(dǎo)入行為。
2.1.1 快速體驗(yàn)
2.2 導(dǎo)入包
2.2.1 方法一
import 包名.模塊名包名.模塊名.目標(biāo)2.2.1.1 體驗(yàn)
import my_package.my_module1my_package.my_module1.info_print1()2.2.2 方法二
注意:必須在__init__.py文件中添加__all__ = [],控制允許導(dǎo)入的模塊列表。
from 包名 import * 模塊名.目標(biāo)2.2.2.1 體驗(yàn)
from my_package import *my_module1.info_print1()總結(jié)
以上是生活随笔為你收集整理的Python学习之路(四)——Python核心编程3(面向对象、模块_包_异常)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: @SpringBootTest Cano
- 下一篇: oracle 中符号%3e,Oracle