標籤:span 需要 沒有 不同 就會 執行個體化 裝飾器 記憶體 之間
屬性尋找
類有兩種屬性:資料屬性和函數屬性
1、類的資料屬性是所有對象共用的
# 類的資料屬性是所有對象共用的,id是一樣的print(id(OldboyStudent.school)) # 4830576print(id(s1.school)) # 4830576print(id(s2.school)) # 4830576print(id(s3.school)) # 4830576
2、 類的函數屬性是綁定給對象用的,稱為綁定到對象的方法
# 類的函數屬性是綁定給對象使用的,obj.method稱為Binder 方法,記憶體位址都不一樣print(OldboyStudent.learn) # <function OldboyStudent.learn at 0x0000000002879598>print(s1.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866898>>print(s2.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x00000000028669E8>>print(s3.learn) # <bound method OldboyStudent.learn of <__main__.OldboyStudent object at 0x0000000002866F98>>#ps:id是python的實現機制,並不能真實反映記憶體位址,如果有記憶體位址,還是以記憶體位址為準
在obj.name會先從obj自己的名稱空間裡找name,找不到則去類中找,類也找不到就找父類,最後都找不到就拋出異常
Binder 方法
定義類並執行個體化出三個對象
class OldboyStudent: school = ‘oldboy‘ def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def learn(self): print(‘%s is learning‘ % self.name) # 新增self.name def eat(self): print(‘%s is eating‘ % self.name) def sleep(self): print(‘%s is sleeping‘ % self.name)s1 = OldboyStudent(‘李坦克‘, ‘男‘, 18)s2 = OldboyStudent(‘王大炮‘, ‘男‘, 28)s3 = OldboyStudent(‘牛彈琴‘, ‘女‘, 38)
類中定義的函數(沒有被任何裝飾器裝飾的)是累的函數屬性,類可以使用,但必須遵循函數的參數規則,有幾個參數需要傳幾個函數
OldboyStudent.learn(s1) # 李坦克 is learningOldboyStudent.eat(s2) # 王大炮 is eatingOldboyStudent.sleep(s3) # 牛彈琴 is sleeping
類中定義的函數(沒有被任何裝飾器裝飾的),其實主要是給對象使用的,而且是綁定到對的,雖然所有對象指向的都是相同的功能,但是綁定到不同的對象就是不同的Binder 方法
強調:綁定到對象的方法的特殊之處在於,綁定給誰就由誰來調用,誰來調用,就會將誰本身當做第一個參數轉給方法,即自動傳值(方法__init__也是一樣的道理)
s1.learn() # 等同於OldboyStudent.learn(s1)s2.eat() # 等同於OldboyStudent.eat(s2)s3.sleep() # 等同於OldboyStudent.sleep(s3)
注意:綁定到對象的方法的這種自動傳值的特徵,決定了在類中定義的函數都要預設寫一個參數self,self可以是任意名字,但是約定俗成地寫在self
類即類型
Python中一切皆為對象,且Python3中類與類型是一個概念,類型就是類
#類型dict就是類dict>>> list<class ‘list‘>#執行個體化的到3個對象l1,l2,l3>>> l1=list()>>> l2=list()>>> l3=list()#三個對象都有Binder 方法append,是相同的功能,但記憶體位址不同>>> l1.append<built-in method append of list object at 0x10b482b48>>>> l2.append<built-in method append of list object at 0x10b482b88>>>> l3.append<built-in method append of list object at 0x10b482bc8>#操作Binder 方法l1.append(3),就是在往l1添加3,絕對不會將3添加到l2或l3>>> l1.append(3)>>> l1[3]>>> l2[]>>> l3[]#調用類list.append(l3,111)等同於l3.append(111)>>> list.append(l3,111) #l3.append(111)>>> l3[111]
小節練習
# 練習1:編寫一個學生類,產生一堆學生對象, (5分鐘)## 要求:## 有一個計數器(屬性),統計總共執行個體了多少個對象class Student(): school = "家裡蹲大學" count = 0 def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex Student.count += 1 def learn(self): print(‘%s is learning‘ % self.name)s1 = Student(‘張三‘, ‘男‘, 22)s1.learn()s2 = Student(‘李四‘, ‘女‘, 28)print(Student.count)print(s1.count)# 練習2:模仿三國定義兩個英雄類, (10分鐘)## 要求:## 英雄需要有暱稱、攻擊力、生命值等屬性;# 執行個體化出兩個英雄對象;# 英雄之間可以互毆,被毆打的一方掉血,血量小於0則判定為死亡。class Garen: camp = ‘Demacia‘ def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity if enemy.life_value <= 0: print(‘%s已經死亡‘ % self.nickname)class Riven: camp = ‘Noxus‘ def __init__(self, nickname, life_value, aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attack(self, enemy): enemy.life_value -= self.aggresivity if enemy.life_value <= 0: print(‘%s已經死亡‘ % self.nickname)g1 = Garen(‘曹操‘, 100, 30)r1 = Riven(‘劉備‘, 100, 50)print(r1.life_value)g1.attack(r1)g1.attack(r1)g1.attack(r1)g1.attack(r1)print(r1.life_value)
python:屬性尋找與Binder 方法