【面向对象编程】(2) 类属性的定义及使用;__repr__()方法
各位同學好,在上一節中我們學習了類實例化的基本方法:https://blog.csdn.net/dgvv4/article/details/122275348?spm=1001.2014.3001.5501
今天在上一節的基礎上繼續補充,和大家分享一下類屬性的定義及使用方法。
1. 定義類屬性
在定義的類中,在初始化函數之前定義到變量稱為類屬性,是這個類特有的。一旦類實例化之后,那么實例對象默認就可以訪問這個類屬性。
綁定在一個實例上的屬性不會影響其他實例,但是,類本身也是一個對象,如果在類上綁定一個屬性,則所有實例都可以訪問類的屬性,并且,所有實例訪問的類屬性都是同一個。也就是說,實例屬性每個實例各自擁有,互相獨立,而類屬性有且只有一份。
這里定義的類屬性 pay_rate,不僅可以通過類來訪問?Item.pay_rate,也能通過實例來訪問 item1.pay_rate。我們可以通過 __dict__ 查看實例或者類的屬性,如最后兩行代碼,可見類屬性pay_rate是屬于類Item特有的。
#(1)創建類
class Item: #(2)創建類屬性pay_rate = 0.8 # 定義類屬性,代表商品折扣8折#(3)初始化# 第一個參數 self代表類實例化對象,屬性name需要字符串類型,屬性price需要浮點類型,屬性quantity默認值為10def __init__(self, name:str, price:float, quantity=10):# 指定輸入輸入值的范圍,如果不符合就報錯,報錯內容是逗號后面的assert price >=0, f'price {price} cannot smaller than 0'assert quantity >=0, f'quantity {quantity} cannot smaller than 0'# 屬性分配self.name = nameself.price = priceself.quantity = quantity#(3)在類中定義方法,第一個參數默認是self實例化對象def calculate_total_price(self):# 返回單價和數量的乘積return self.price * self.quantity#(4)類實例化
item1 = Item('phone', 100, 5) # Item類的實例化對象item1,傳入各屬性對應的值
item2 = Item('MacBook', 1000, 3) #(5)調用類中的方法
res = item1.calculate_total_price()
print(res) # 500#(6)通過類本身訪問類屬性
print(Item.pay_rate) # 0.8#(7)通過實例化對象訪問類屬性
print(item1.pay_rate) # 0.8
print(item2.pay_rate) # 0.8# 打印類的所有屬性
print(Item.__dict__) # {'__module__': '__main__', 'pay_rate': 0.8, '__init__': <function Item.__init__ at 0x0000023A6989A940>, 'calculate_total_price': <function Item.calculate_total_price at 0x0000023A6989ACA0>, '__dict__': <attribute '__dict__' of 'Item' objects>, '__weakref__': <attribute '__weakref__' of 'Item' objects>, '__doc__': None}
# 打印實例的所有屬性
print(item1.__dict__) # {'name': 'phone', 'price': 100, 'quantity': 5}
2. 類屬性的應用
在類中定義了一個方法,調用類屬性用于計算,self.price * Item.pay_rate,其中price調用的是實例屬性,pay_rate調用的是類屬性,類屬性是不變的。
如下代碼中,實例屬性 price 可根據不同的實例展現不同的值,而類屬性 pay_rate 是固定的,通過實例訪問類屬性改變它的值 item2.pay_rate = 0.5,不會影響 Item.pay_rate 的結果。
#(1)創建類
class Item: #(2)創建類屬性pay_rate = 0.8 # 定義類屬性,代表商品折扣8折#(3)初始化,self代表類實例化對象,屬性name需要字符串類型,屬性price需要浮點類型,屬性quantity默認值為10def __init__(self, name:str, price:float, quantity=10):# 指定輸入輸入值的范圍,如果不符合就報錯,報錯內容是逗號后面的assert price >=0, f'price {price} cannot smaller than 0'assert quantity >=0, f'quantity {quantity} cannot smaller than 0'# 屬性分配self.name = nameself.price = priceself.quantity = quantity#(4)在類中定義方法,第一個參數默認是self實例化對象def calculate_total_price(self):# 返回單價和數量的乘積return self.price * self.quantity#(5)調用類屬性# 在類中定義方法,用于計算商品折扣def apply_discount(self):# 計算新的價格,pay_rate是Item類自身的屬性,在類的內部不能用實例屬性self.pay_rate來調用它self.price = self.price * Item.pay_rate#(6)Item類的實例化對象item1
item1 = Item('phone', 100, 5)
print(item1.price) # 100#(7)調用商品打折的方法
item1.apply_discount()
print(item1.price) # 80.0#(8)實例化對象item2
item2 = Item('MacBook', 1000, 3)
print(item2.price) # 1000# 通過實例化屬性改變類屬性
item2.pay_rate = 0.5 # 沒有發生變化# 調用類方法
item2.apply_discount()
print(item2.price) # 800.0
3. 不同的實例分配不同的類屬性
就拿這個案例來說,如果并不是所有的商品都打8折,假如phone打8折,而MacBook打5折,計算時,肯定不能每一次都去重新寫類屬性。
這時候在調用類屬性時,需通過實例訪問類屬性,用于計算。如下面代碼中?self.price = self.price * self.pay_rate,這里的price屬性和pay_rate屬性都是通過實例來訪問的,可以通過實例來改變各屬性對應的值。item2.pay_rate = 0.5,就可以將?self.pay_rate 改為0.5。
如果是通過類來訪問的類屬性,那么調用該方法時,即使外部給實例屬性賦予了新的值,但是這里仍使用的是類屬性的值,沒有改變。
#(1)創建類
class Item:#(2)創建類屬性pay_rate = 0.8 # 創建類屬性,代表商品折扣8折#(3)初始化,self代表類實例化對象,屬性name需要字符串類型,屬性price需要浮點類型,屬性quantity默認值為10def __init__(self, name:str, price:float, quantity=10):# 指定輸入輸入值的范圍,如果不符合就報錯,報錯內容是逗號后面的assert price >=0, f'price {price} cannot smaller than 0'assert quantity >=0, f'quantity {quantity} cannot smaller than 0'# 屬性分配self.name = nameself.price = priceself.quantity = quantity#(4)在類中定義方法,第一個參數默認是self實例化對象def calculate_total_price(self):# 返回單價和數量的乘積return self.price * self.quantity#(5)調用類屬性# 在類中定義方法,用于計算商品折扣def apply_discount(self):# 計算新的價格,類屬性pay_rate通過實例屬性來訪問,可以在外部通過實例來訪問這個屬性,并改變這個屬性的值self.price = self.price * self.pay_rate#(6)類實例化對象
item1 = Item('phone', 100, 5)#(7)調用類中的商品打折方法(該方法調用類屬性)
item1.apply_discount() # 默認8折
print(item1.price) # 80.0# 類實例化對象
item2 = Item('MacBook', 1000, 3)
# 通過實例對象訪問類屬性,并改變該實例所對應的類屬性的值
item2.pay_rate = 0.5
# 調用打折方法,已經改變了屬性的值
item2.apply_discount()
print(item2.price) # 500.0
4. 訪問多個實例的屬性
現在有很多實例化對象,如何去批量訪問這些實例的屬性呢。定義一個列表形式的類屬性 all_instance,在每一次初始化之后,將定義好了的實例化對象追加到列表中,Item.all_instance.append(self) ,這里是通過類來訪問類屬性,這樣外部就改變不了類屬性?all_instance 中的值。最后通過一個for循環遍歷類屬性中的所有實例,打印實例的屬性結果。
#(1)創建類
class Item:#(2)創建類屬性pay_rate = 0.8 # 創建類屬性all_instance = [] # 存放所有已經定義的實例#(3)初始化,指定需要傳入的實例屬性的值是什么類型的def __init__(self, name:str, price:float, quantity=10):# 指定輸入輸入值的范圍,如果不符合就報錯,報錯內容是逗號后面的assert price >=0, f'price {price} cannot smaller than 0'assert quantity >=0, f'quantity {quantity} cannot smaller than 0'# 分配屬性self.name = nameself.price = priceself.quantity = quantity# 每次初始化后都會將創建好了的實例存追加到列表中# 這里通過類訪問的類屬性,在外部就改變不了all_instance的值Item.all_instance.append(self) # 將實例self追加到列表中#(4)定義計算總價的方法def calculate_total_price(self):# 返回單價乘數量return self.price * self.quantity#(5)定義打折方法,調用類屬性def price_discount(self):# 通過實例訪問類屬性pay_rate,可在外部通過實例改變類屬性的默認值self.price = self.price * self.pay_rate#(6)實例化了很多對象,在完成類初始化之后,都將這些實例存放在all_instance屬性中
item1 = Item('phone', 100, 5)
item2 = Item('MacBook', 200, 6)
item3 = Item('ipad', 300, 7)
item4 = Item('Mouse', 400, 8)
item5 = Item('keyboard', 500, 9)#(7)訪問所有實例化對象
for instance in Item.all_instance:# 打印所有實例的屬性print('name:', instance.price, 'price:', instance.price, 'quantity:', instance.quantity)#(8)直接輸出實例化對象
print(Item.all_instance)
# [<__main__.Item object at 0x0000023A698B7D00>, <__main__.Item object at 0x0000023A698B7250>, <__main__.Item object at 0x0000023A698B7610>, <__main__.Item object at 0x0000023A698B7A60>, <__main__.Item object at 0x0000023A698B7B50>]
5. __repr__() 顯示屬性
如上面代碼的第(8)步,直接輸出實例化對象時 print(Item.all_instance),本意往往是想了解該對象的基本信息,但默認情況下,我們得到的信息只會是“類名+object at+內存地址”。
當我們輸出某個實例化對象時,其調用的就是該對象的 __repr__() 方法,輸出的是該方法的返回值。?print(Item.all_instance)? 等同于執行 print(Item.all_instance.__repr__()),程序的輸出結果是一樣的。
因此,在類中定義 __repr__() 的輸出格式 return f"Item('{self.name}', {self.price}, {self.quantity})",這樣的話,在外部輸出實例化對象時,就可以按照這個格式打印結果了。
#(1)創建類
class Item:#(2)創建類屬性pay_rate = 0.8 # 創建類屬性all_instance = [] # 存放所有已經定義的實例#(3)初始化,指定需要傳入的實例屬性的值是什么類型的def __init__(self, name:str, price:float, quantity=10):# 指定輸入輸入值的范圍,如果不符合就報錯,報錯內容是逗號后面的assert price >=0, f'price {price} cannot smaller than 0'assert quantity >=0, f'quantity {quantity} cannot smaller than 0'# 分配屬性self.name = nameself.price = priceself.quantity = quantity# 每次初始化后都會將創建好了的實例存追加到列表中# 這里通過類訪問的類屬性,在外部就改變不了all_instance的值Item.all_instance.append(self) # 將實例self追加到列表中#(4)定義計算總價的方法def calculate_total_price(self):# 返回單價乘數量return self.price * self.quantity#(5)定義打折方法,調用類屬性def price_discount(self):# 通過實例訪問類屬性pay_rate,可在外部通過實例改變類屬性的默認值self.price = self.price * self.pay_rate#(6)顯示屬性,接收實例def __repr__(self):return f"Item('{self.name}', {self.price}, {self.quantity})"#(7)實例化多個對象
item1 = Item('phone', 100, 5)
item2 = Item('MacBook', 200, 6)
item3 = Item('ipad', 300, 7)
item4 = Item('Mouse', 400, 8)
item5 = Item('keyboard', 500, 9)#(8)輸出實例化對象,調用的就是該對象的 __repr__() 方法,輸出的是該方法的返回值
print(Item.all_instance)
# [Item('phone', 100, 5), Item('MacBook', 200, 6), Item('ipad', 300, 7), Item('Mouse', 400, 8), Item('keyboard', 500, 9)]
總結
以上是生活随笔為你收集整理的【面向对象编程】(2) 类属性的定义及使用;__repr__()方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【机器视觉案例】(9) AI视觉,手势控
- 下一篇: 【机器视觉案例】(10) AI视觉搭积木