Python基础day08【面向对象(类、对象、属性)、魔方方法(init、str、del、repr)】
- 視頻、源碼、課件、軟件、筆記:超全面Python基礎入門教程【十天課程】博客筆記匯總表【黑馬程序員】
?
目錄
0、復習
1、類外部添加和獲取對象屬性
2、類內部操作屬性
3、魔法方法
3.1、__init__()[掌握]
3.1.1、單參__init__()
3.1.2、多參__init__()
3.2、__str__()[掌握]
3.3、__del__()[理解]
4、案例:烤地瓜
烤地瓜-調料版
5、補充:查看對象的引用計數
6、案例:搬家具
打印家具信息
7、區分__str__()與__repr__()
8、附錄:魔方方法(__str__對比__repr__)
8.1、引言
8.2、分析
8.2.1、重寫__str__()方法
8.2.2、重寫__repr__()方法
8.3、總結
9、總結
0、復習
二進制文件的讀寫,不需要指定encoding參數。
基礎班考試:單選、多選、代碼題。
while True: pass 使用場景:在書寫代碼的時候,不確定循環一共執行多少次,即不知道循環在什么時候結束(具體結束的時間),在運行代碼的過程中才能確定,在代碼中進行if判斷,如果條件不滿足,就使用break終止循環。
my_list = list() ?# 創建列表類對象
my_dict = dict() ?# 創建字典類對象
my_tuple = tuple() ?# 創建元組類對象
class 類名(object):
? ? def 函數名(self):
? ? ? ? pass
1、類外部添加和獲取對象屬性
每個對象,會保存自己的屬性值,不同對象的屬性值之間沒有關聯。
class Dog(object):def play(self):print('小狗快樂的拆家中...')# 創建對象 dog1 = Dog() dog1.play() # 小狗快樂的拆家中...# 給對象添加屬性:對象.屬性名 = 屬性值 dog1.name = '大黃' # 給dog對象添加name屬性,屬性值是大黃 dog1.age = 2 # 給dog對象添加age屬性,屬性值是2# 獲取對象的屬性值:對象.屬性名 print(dog1.name) # 大黃 print(dog1.age) # 2# 修改屬性值和添加一樣,存在就是修改;不存在就是添加 dog1.age = 3 # age屬性已經存在,所以是修改屬性值 print(dog1.age) # 3dog2 = Dog() # 新創建一個對象dog2 dog2.name = '小白' print(dog2.name) # 小白2、類內部操作屬性
self 就是一個形參的名字,可以寫成其他的形參名,一般不修改這個名字,默認是self。
class Dog(object):# self作為類中方法的第一個形參,在通過對象調用方法的時候,不需要手動地傳遞實參值,# 是python解釋器自動將調用該方法的對象傳遞給self, 所以self這個形參代表的是對象def play(self):print(f'self: {id(self)}')print(f'小狗 {self.name} 在快樂地拆家中...')# 創建對象 dog1 = Dog() dog1.name = '大黃' print(f"dog : {id(dog1)}") dog1.play() print('-------------------------') dog2 = Dog() dog2.name = '小白' print(f"dog2: {id(dog2)}") dog2.play()3、魔法方法
?在 python 的類中有一類方法,這類方法以`兩個下劃線開頭`和`兩個下劃線結尾`,并且在`滿足某個特定條件的情況下,會自動調用`。這類方法,稱為魔法方法。
如何學習魔法方法:1.魔法方法在什么情況下會自動調用;2.這個魔法方法有什么作用;3.這個魔法方法有哪些注意事項。
3.1、__init__()[掌握]
調用時機:在創建對象之后,會立即調用。類似于Java中的構造方法。
作用:
?? ?1.用來給對象添加屬性,給對象屬性一個初始值(構造函數);
?? ?2.代碼的業務需求,每創建一個對象,都需要執行的代碼可以寫在`__init__ `中。
注意點:如果`__init__`方法中,有除了 self 之外的形參,那么在創建的對象的時候,需要給額外的形參傳遞實參值`類名(實參)`。
3.1.1、單參__init__()
class Dog(object):def __init__(self): # self是對象print('我是__init__方法,我被調用了!')# 對象.屬性名 = 屬性值self.name = '小狗'# 創建對象 Dog() # 我是__init__方法,我被調用了!dog1 = Dog() # 我是__init__方法,我被調用了! print(dog1.name) # 小狗dog2 = Dog() # 我是__init__方法,我被調用了! print(dog2.name) # 小狗3.1.2、多參__init__()
class Dog(object):def __init__(self, name): # self是對象print('我是__init__方法,我被調用了!')# 對象.屬性名 = 屬性值self.name = namedef play(self):print(f"小狗{self.name}快樂地拆家中...")# 創建對象 類名(實參值) dog1 = Dog('大黃') # 我是__init__方法,我被調用了! print(dog1.name) # 大黃 dog1.play() # 小狗大黃快樂地拆家中...dog2 = Dog('小白') # 我是__init__方法,我被調用了! print(dog2.name) # 小白 dog2.play() # 小狗小白快樂地拆家中...3.2、__str__()[掌握]
調用時機:
?? ?1.`print(對象)`,會自動調用`__str__`方法,打印輸出的結果是`__str__`方法的返回值;
?? ?2.`str(對象)`類型轉換,將自定義對象轉換為字符串的時候,會自動調用。
應用:
?? ?1.打印對象的時候,輸出一些屬性信息;
?? ?2.需要將對象轉換為字符串類型的時候。
注意點:`方法必須返回一個字符串`,只有 self 一個參數。
class Dog(object):def __init__(self, name, age):# 添加屬性self.name = nameself.age = agedef __str__(self):print('我是__str__, 我被調用了...')# 必須返回一個字符串return f"小狗的名字是{self.name}、年齡是{self.age}。"# 創建對象 dog = Dog('大黃', 2) print(dog) # 沒有定義__str__方法,print(對象)默認輸出對象的引用地址 # <__main__.Dog object at 0x0000020F33D574C0>str_dog = str(dog) # 沒有定義__str__方法,類型轉換,賦值的也是引用地址 print(str_dog) # <__main__.Dog object at 0x0000020F33D574C0>3.3、__del__()[理解]
__del__()析構函數。調用時機:對象在內存中被銷毀刪除的時候(引用計數為 0)會自動調用__del__方法。
? ?1.程序代碼運行結束,在程序運行過程中,創建的所有對象和變量都會被刪除銷毀;
? ?2.使用`del 變量`,將這個對象的引用計數變為 0。會自動調用 __del__ 方法。
應用場景:對象被刪除銷毀的時候,要書寫的代碼可以寫在`__del__`中,一般很少使用。
引用計數:是python內存管理的一種機制,是指一塊內存,有多少個變量在引用:
? ?1. 當一個變量,引用一塊內存的時候,引用計數加 1;
? ?2. 當刪除一個變量,或者這個變量不再引用這塊內存,引用計數減 1;
? ?3. 當內存的引用計數變為 0 的時候,這塊內存被刪除,內存中的數據被銷毀。
my_list = [1, 2] ?# 1
my_list1 = my_list # 2
del my_list ?# 1
del my_list1 # 0
4、案例:烤地瓜
封裝的小套路:
? ?1.根據文字的描述信息確定對象,對象有什么,就是屬性;
? ?2.根據文字的描述信息,對象能干什么,就是方法;
? ?3.根據文字的描述信息,確定方法怎么書寫。
烤地瓜規則:
類名:地瓜類 Potato
屬性:
? ? 狀態 status='生的'
? ? 燒烤總時間 total_time = 0
方法:
? ? def cook(self, 燒烤時間):
? ? ? ? 計算燒烤的總時間
? ? ? ? 修改地瓜的狀態的
? ? ? ? pass
? ? 輸出信息 ?__str__()
? ? 定義屬性 ?__init__()
烤地瓜-調料版
屬性:調料: name_list = []
方法:添加調料 add()
5、補充:查看對象的引用計數
import sysclass Dog(object):passdog = Dog() # 1 print(sys.getrefcount(dog)) # 2 顯示的時候,會比實際的多一個dog1 = dog # 2 print(sys.getrefcount(dog)) # 3 顯示的時候,會比實際的多一個del dog # 1 print(sys.getrefcount(dog1)) # 2 顯示的時候,會比實際的多一個6、案例:搬家具
搬家具規則:
類名:家具類 Furniture?
屬性:
? ? 類型 name?
? ? 面積 area
方法:
? ? 輸出家具信息 ?__str__?
? ? 定義屬性 ?__init__?
--------------------------------------------
類名:房子類 House
屬性:
? ? 地址 address
? ? 面積 h_area
? ? 家具列表 ?furniture_list = []
方法:
? ? 添加家具 ?add_furniture()
? ? 輸出房子信息 __str__
? ? 定義屬性 ?__init__
打印家具信息
# 定義家具類 Furniture 類 class Furniture(object):def __init__(self, name, area):# 類型self.name = name# 面積self.area = areadef __str__(self):return f'家具的類型<{self.name}>, 占地面積<{self.area}>平。'# 定義房子類 class House(object):def __init__(self, address, area):self.address = addressself.h_area = areaself.furniture_list = []self.free_area = area # 房子的剩余面積def add_furniture(self, obj_furniture):""" 添加家具 obj_furniture: 家具類的對象"""if self.free_area > obj_furniture.area:self.furniture_list.append(obj_furniture)# 修改剩余面積self.free_area -= obj_furniture.areaprint(f'家具<{obj_furniture.name}>添加成功。')else:print('添加失敗,換個大房子吧。')def __str__(self):# 自定義家具類,將該類的對象添加到列表中(容器), 直接打印列表,顯示的是自定義對象的引用地址# [家具對象, 家具對象, ... ] ---> [家具類型, 家具類型, ...]if self.furniture_list:buf_list = [obj.name for obj in self.furniture_list]return f"房子的地址為<{self.address}>, 占地面積為<{self.h_area}>, 剩余面積為{self.free_area}, " \f"家具有<{','.join(buf_list)}>。"else:return f"房子的地址為<{self.address}>, 占地面積為<{self.h_area}>, 剩余面積為{self.free_area}, " \f"還沒有購買家具。"# 創建家具對象 bed = Furniture('豪華雙人床', 15) print(bed)# 創建一個房子類對象 house = House('意大利農場', 100) print(house)house.add_furniture(bed) print(house)sofa = Furniture('柔軟大沙發', 8) print(sofa)house.add_furniture(sofa) print(house)7、區分__str__()與__repr__()
my_list = ['hello', 'python', 'cpp'] # 列表中存儲了三個字符串對象 print(my_list) # ['hello', 'python', 'cpp']class Dog(object):def __init__(self, name, age):self.name = nameself.age = agedef __str__(self):return f'{self.name}, {self.age}'def __repr__(self):"""repr方法和str方法,非常類似,也是必須返回一個字符串!"""return f"{self.name}"# 將三個Dog類的對象添加到列表中 my_list1 = [Dog('大黃', 2), Dog('小白', 4), Dog('小花', 6)] print(my_list1) # [大黃, 小白, 小花]dog = Dog('大黃', 2) print(dog) # __str__ 大黃, 28、附錄:魔方方法(__str__對比__repr__)
python中的魔法方法:`__str__` 和`__repr__`.pdf
8.1、引言
在學習?向對象的時候,我們知道在 python 中有?類特殊的?法,叫做魔法?法,這種?法的特點如下:
? ?1. ?法定義的時候以兩個下劃線開頭和兩個下劃線結尾:如__init__ 、 __str__ 和__repr__;
? ?2. 這類?法?般不需要我們?動調?,在滿?某個條件的時候會?動調?,這個滿?的條件我們可以稱為調?時機。
在Python中有兩個魔法?法都是?來描述對象信息的,__str__和__repr__,那為什么要定義兩個這樣的?法呢,其實是它們設計的?的是不?樣的:
? ?1.__repr__的?標是準確性,或者說,__repr__的結果是讓解釋器?的;
? ?2.__str__的?標是可讀性,或者說,__str__的結果是讓?看的。
8.2、分析
那下邊,我們詳細地來看?下,他們的?法:在不重寫__str__和__repr__的情況下,打印對象的 輸出結果不太友好,是對象的內存地址,即 id的結果。
class Person(object): # 定義 Person 類def __init__(self, name):self.name = namep = Person("isaac")# 以下為測試輸出的結果: print(p) # <__main__.Person object at 0x0000016FB4E0E220> p # <__main__.Person object at 0x0000016FB4E0E220> p.__str__() # '<__main__.Person object at 0x0000016FB4E0E220>' p.__repr__() # '<__main__.Person object at 0x0000016FB4E0E220>'這樣的輸出結果,并不是我們想要的結果,此時我們重寫__str__和__repr__?法。
8.2.1、重寫__str__()方法
class Person(object): # 定義 Person 類def __init__(self, name):self.name = namedef __str__(self):return "__str__ ?法 " + self.namep = Person("isaac")# 以下為測試輸出的結果: print(p) str(p) f"{p}" p.__str__() p此時我們發現在使? print 打印對象、對象的格式化輸出以及調?str?法,調?的都是__str__?法。但在交互環境下,直接輸出對象的時候,沒有調?__str__?法,輸出的結果仍然是id的結果。
8.2.2、重寫__repr__()方法
class Person(object): # 定義 Person 類:def __init__(self, name):self.name = namedef __str__(self):return "__str__ ?法 " + self.namedef __repr__(self):return "__repr__ ?法 " + self.namep = Person("isaac")# 以下為測試輸出的結果: p p.__repr__() print(p)通過簡單的對?,我們發現,在交互環境下,直接輸出對象,調?的__repr__?法。
另外還需要注意的是,如果將對象放在容器中進?輸出,調?的是__repr__?法。
8.3、總結
Python 中的__str__和__repr__?法都是?來顯示的,即描述對象信息的。
1.__str__的?標是可讀性,或者說,__str__的結果是讓?看的。主要?來打印,即print操作,
2.__repr__的?標是準確性,或者說,__repr__的結果是讓解釋器?的。__repr__?于交互模式下提示回應,
3.如果沒有重寫__str__?法,但重寫了__repr__?法時,所有調?__str__的時機都會調?__repr__?法。
9、總結
總結
以上是生活随笔為你收集整理的Python基础day08【面向对象(类、对象、属性)、魔方方法(init、str、del、repr)】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python基础day07 作业解析【文
- 下一篇: websocket python爬虫_p