日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python基础day08【面向对象(类、对象、属性)、魔方方法(init、str、del、repr)】

發布時間:2024/9/30 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

class Dog(object):def __init__(self, name, age):# 添加屬性self.name = nameself.age = agedef __str__(self):# 必須返回一個字符串return f"小狗的名字是{self.name}, 年齡是{self.age}!"def __del__(self):print(f'我是__del__ 方法, 我被調用了, {self.name}被銷毀了...')# 創建一個對象 # dog = Dog('大黃', 2) # dog1 = Dog('小白', 1)dog = Dog('小花', 3) # 小花 引用計數為1 dog2 = dog # 小花 引用計數2 print('第一次刪除之前。') del dog # dog變量不能使用了, 小花對象引用計數變為1 print('第一次刪除之后。') print('第二次刪除之前。') del dog2 # dog2變量不能使用, 小花對象的引用計數變為0, 會立即__del__方法 print('第二次刪除之后。')

4、案例:烤地瓜

封裝的小套路:
? ?1.根據文字的描述信息確定對象,對象有什么,就是屬性;
? ?2.根據文字的描述信息,對象能干什么,就是方法;
? ?3.根據文字的描述信息,確定方法怎么書寫。

烤地瓜規則:

  • 地瓜有自己的狀態,默認是生的,地瓜可以進行燒烤。
  • 地瓜有自己燒烤的總時間,由每次燒烤的時間累加得出。
  • 地瓜燒烤時,需要提供本次燒烤的時間。
  • 地瓜燒烤時,地瓜狀態隨著燒烤總時間的變化而改變:[0,3) 生的、[3,6) 半生不熟、[6,8) 熟了、>=8 烤糊了。
  • 輸出地瓜信息時,可以顯示地瓜的狀態和燒烤的總時間。
  • 類名:地瓜類 Potato
    屬性:
    ? ? 狀態 status='生的'
    ? ? 燒烤總時間 total_time = 0
    方法:
    ? ? def cook(self, 燒烤時間):
    ? ? ? ? 計算燒烤的總時間
    ? ? ? ? 修改地瓜的狀態的
    ? ? ? ? pass
    ? ? 輸出信息 ?__str__()
    ? ? 定義屬性 ?__init__()

    class Potato(object):def __init__(self):self.status = '生的'self.total_time = 0def cook(self, time):# 計算總時間self.total_time += time# 修改地瓜的狀態if self.total_time < 3:self.status = '生的'elif self.total_time < 6:self.status = '半生不熟的'elif self.total_time < 8:self.status = '熟了'else:self.status = '烤糊了'def __str__(self):return f"地瓜的狀態<<{self.status}>>, 燒烤總時間為<{self.total_time}>"# 創建對象 potato = Potato() print(potato) # 地瓜的狀態<<生的>>, 燒烤總時間為<0>potato.cook(4) print(potato) # 地瓜的狀態<<半生不熟的>>, 燒烤總時間為<4>potato.cook(3) print(potato) # 地瓜的狀態<<熟了>>, 燒烤總時間為<7>

    烤地瓜-調料版

    屬性:調料: name_list = []
    方法:添加調料 add()

    class Potato(object):def __init__(self):self.status = '生的'self.total_time = 0self.name_list = [] # 保存調料的列表def cook(self, time):# 計算總時間self.total_time += time# 修改地瓜的狀態if self.total_time < 3:self.status = '生的'elif self.total_time < 6:self.status = '半生不熟的'elif self.total_time < 8:self.status = '熟了'else:self.status = '烤糊了'def __str__(self):# buf_list = str(self.name_list) # str([]) ===> '[]'# buf_list = buf_list.replace('[', '')# 字符串.join(列表):將字符串添加到列表中的每個元素之間,組成新的字符串。buf = ','.join(self.name_list) # 將列表中的字符串組成一個大的字符串if self.name_list:return f"地瓜的狀態<<{self.status}>>, 燒烤總時間為<{self.total_time}>, 已添加的調料有: {buf}!"else:return f"地瓜的狀態<<{self.status}>>, 燒烤總時間為<{self.total_time}>, 還沒有添加調料!"def add(self, name): # 添加調料的方法self.name_list.append(name)# 創建對象 potato = Potato() print(potato) # 地瓜的狀態<<生的>>, 燒烤總時間為<0>, 還沒有添加調料!potato.add('油') potato.cook(4) potato.add('辣椒面') print(potato) # 地瓜的狀態<<半生不熟的>>, 燒烤總時間為<4>, 已添加的調料有: 油,辣椒面!potato.cook(3) potato.add('孜然') print(potato) # 地瓜的狀態<<熟了>>, 燒烤總時間為<7>, 已添加的調料有: 油,辣椒面,孜然!

    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):return f"房子的地址為<{self.address}>, 占地面積為<{self.h_area}>, 剩余面積為{self.free_area}。"# 創建家具對象 bed = Furniture('豪華雙人床', 15) print(bed)# 創建一個房子類對象 house = House('意大利農場', 100) print(house) house.add_furniture(bed) print(house)

    打印家具信息

    # 定義家具類 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__ 大黃, 2

    8、附錄:魔方方法(__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)】的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。