python基礎之面向對象編程介紹、類和對象
面向對象變成介紹
面向過程編程
核心是過程(流水線式思維),過程即解決問題的步驟,面向過程的設計就好比精心設計好一條流水線,考慮周全什麽時候處理什麽東西。主要應用在一旦完成很少修改的地方,如linux內核、git、apache服務器等
優點:極大的降低了程序的設計復雜度
缺點:可擴展性差,改動一個地方很可能要改多個地方,牽一發而動全身
面向對象編程:不是編程的全部,只是用來解決軟件可擴展性的
核心是對象(上帝式思維),對象作為程序的基本單元,一個對象包含了數據和操作數據的函數。面向對象就是把計算機程序作為一個對象集合,每隔對象都能接收其他對象傳來的消息,計算機程序的執行就是就是一系列消息在各個對象之間傳遞。主要應用在需求經常變化的軟件,一般需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等
優點:解決了程序的可擴展性差的問題,對某一個對象修改會立刻反映到整個程序體系,如lol對一個英雄屬性的修改(萬年削弱從未被加強)
缺點:可控性差,無法預測程序執行結果,如lol每局遊戲的結果
類和對象
對象的概念
對象也叫做實例,是通過類產生的,對象就是數據屬性和方法屬性的結合體,比如lol中的英雄,一個英雄就是一個對象,具備生命值、藍條攻擊力等數據屬性,又具備qwer四個技能屬於方法屬性。
類的概念
類包含了一組對象的相同屬性部分,還是說lol中的英雄,所有的英雄都有名字、標簽(坦克戰士法師)、生命值、藍條攻擊力等,雖然具體的值不同,但是都可以包含在類中去生成。
在python中,用變量表示是數據屬性,用函數表示方法屬性。
在現實生活中,先有對象後有類,比如先有的人,後有的人類的概念,而在編程中,是先有的類,後有的對象,類生成對象。
聲明一個類:和函數的定義類似
定義函數:通過def關鍵字
1 def functionName(args): 2 ‘函數文檔字符串‘ 3 函數體
定義類:通過cless關鍵字,類的名字一般開頭大寫,為了和函數區分
1 ‘‘‘ 2 class 類名: 3 ‘類的文檔字符串‘ 4 類體 5 ‘‘‘ 6 #我們創建一個類Data類, 7 class Data: 8 pass
示例:定義一個中國人的類
首先分析中國人的特征,首先國籍必須是屬於中國,然後還要是個人,那麽人都會做什麽(吃喝拉撒睡說話)等等,另外每個人還有自己特有的屬性,比如名字身高生日等
偽代碼分析(只是分析):
chinese # 例如共有屬性有 country=‘china‘ #國籍中國 language=‘chinese‘ #語言為中文,地方語言、少數民族語言可列為特有屬性 # 會的技能 def talk(self): print(‘is talking‘) def eat(self): print(‘is eating‘) def sleep(self): print(‘is eating‘) def work(self): print(‘is working‘) # 等一系列人類含有的技能
#特有屬性
name=name
age=age
sex=sex
代碼定義:__init__函數和self會在下面說明
1 class Chinese: 2 # 共同的特征:國籍和語言 3 country = ‘China‘ 4 language = ‘chinese‘ 5 # __init__(p1, ‘zhangsan‘, ‘man‘, 73) 6 def __init__(self,name,sex,age): 7 #只用於初始化的活,不能有返回值,用於定義特有的屬性 8 self.name=name #p1.name=‘zhangsan‘ 9 self.sex=sex #p1.sex=‘man‘ 10 self.age=age #p1.age=73 11 # 共同的技能 12 def talk(self): 13 print(‘is talking‘) 14 def eat(self): 15 print(‘is eating‘) 16 def sleep(self): 17 print(‘is eating‘) 18 def work(self): 19 print(‘is working‘)
類的屬性引用:
1 print(Chinese.__dict__) #以字典的方式返回Chinese的所有屬性,或者用dir(類名)查詢 2 print(Chinese.language) #查看Chinese的language屬性 3 print(Chinese.work) #查看Chinese的work屬性 4 Chinese.language=‘putonghua‘ #修改類的language屬性 5 Chinese.complexion=‘yellow‘ #增加一條膚色屬性 6 del Chinese.complexion #刪除膚色屬性
實例化(生成實例):__init__函數和self說明
1 p1=Chinese(‘zhangsan‘,‘man‘,73) #生成一個實例,name=‘zhangsan‘ sex=‘man‘ age=73 2 print(p1.__dict__) #以字典的方式返回p1的屬性,不包含類的共同屬性,只有name/sex/age
類名加上括號就是一個實例化的過程,以上生成了一個叫做p1的對象
1 print(p1.__dict__,type(p1)) 2 #輸出結果為 3 {‘name‘: ‘zhangsan‘, ‘sex‘: ‘man‘, ‘age‘: 73} <class ‘__main__.Chinese‘>
p1.__dict__輸出的結果為__init__函數所執行後的結果,而__init__函數的位置參數有四個self,name,sex,age,實例化的過程中傳入了‘zhangsan‘,‘man‘,73三個參數對應name,sex,age,而self也是一個位置參數,函數部分我們知道位置參數必須要傳入值,這裏代碼自動會把值p1傳入,也就是實例的名字p1。
而p1的類型為<class ‘__main__.Chinese‘>,如果查看Chinese的類型會發現和p1的一樣,也就是說定義一個類也就是定義了一個類型。
對象的屬性引用:
1 print(p1.language) #p1本身並沒有language屬性,但是可以查到,自己本身雖然沒有,但是從類裏可以拿到 2 # print(p1.run()) #報錯,因為自己和類裏都沒有這個屬性 3 print(p1.work()) 4 p1.city=‘beijing‘ #增加一條屬性,只是針對與對象本身,會增加到p1的屬性字典裏,不會對Chinese有影響 5 del p1.city #刪除一條屬性
結論:
類的數據屬性可以增刪查改
對象的數據屬性可以增刪查改
對象本身並沒有函數屬性,只有自有的數據屬性(__init__函數初始化的屬性或者手動添加的屬性),但是可以通過類調用到,也就是共有的特征和屬性
對象裏通用的數據和函數是引用類的名稱空間
對象的屬性,優先從自己的__dict__字典裏找,如果自己的字典裏沒有,訪問類裏的,如果類裏也沒有,報錯,自己定義的屬性對其他引用了類的相同屬性沒有影響
對象的用法:
class Chinese: obj_list=[] count=0 country = ‘China‘ language = ‘chinese‘ def __init__(self,name,sex,age): self.name=name self.sex=sex self.age=age self.obj_list.append(name) #每次實例化,實例都往pbj_list中添加一個名字 self.count+=1 #每次實例化,實例都將count+1 def sleep(self): print(‘is eating‘) def work(self): print(‘is working‘) p1=Chinese(‘bob‘,‘man‘,18) p2=Chinese(‘natasha‘,‘woman‘,28) p3=Chinese(‘hurry‘,‘man‘,10) print(p1.obj_list,p1.__dict__) print(p2.obj_list,p2.__dict__) print(p3.obj_list,p3.__dict__) print(Chinese.obj_list) #######分割線君####### print(p1.count,id(p1.count)) print(p2.count,id(p2.count)) print(p3.count,id(p3.count)) print(Chinese.count,id(Chinese.count)) 輸出結果: [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘bob‘, ‘sex‘: ‘man‘, ‘age‘: 18, ‘count‘: 1} [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘natasha‘, ‘sex‘: ‘woman‘, ‘age‘: 28, ‘count‘: 1} [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘hurry‘, ‘sex‘: ‘man‘, ‘age‘: 10, ‘count‘: 1} [‘bob‘, ‘natasha‘, ‘hurry‘] 1 1818604608 1 1818604608 1 1818604608 0 1818604576
結果發現:每個實例都沒有obj_list,但是卻有count,一個是可變,一個是不可變,所以類裏可變的數據obj_list可以直接被修改,內存id不會改變,而不可變的數據count只能被重新計算,開辟新的內存空間進行引用,是建立在對象的屬性中,而非類的屬性
1 class Chinese: 2 obj_list=[] 3 count=0 4 country = ‘China‘ 5 language = ‘chinese‘ 6 def __init__(self,name,sex,age): 7 self.name=name 8 self.sex=sex 9 self.age=age 10 Chinese.obj_list.append(name) #每次實例化,Chinese類都往obj_list中添加一個實例名字 11 Chinese.count+=1 #每次實例化,Chinese都將count+1 12 def sleep(self): 13 print(‘is eating‘) 14 def work(self): 15 print(‘is working‘) 16 p1=Chinese(‘bob‘,‘man‘,18) 17 p2=Chinese(‘natasha‘,‘woman‘,28) 18 p3=Chinese(‘hurry‘,‘man‘,10) 19 print(p1.obj_list,p1.__dict__) 20 print(p2.obj_list,p2.__dict__) 21 print(p3.obj_list,p3.__dict__) 22 print(Chinese.obj_list) 23 #######分割線君####### 24 print(p1.count,id(p1.count)) 25 print(p2.count,id(p2.count)) 26 print(p3.count,id(p3.count)) 27 print(Chinese.count,id(Chinese.count)) 28 29 輸出結果 30 [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘bob‘, ‘sex‘: ‘man‘, ‘age‘: 18} 31 [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘natasha‘, ‘sex‘: ‘woman‘, ‘age‘: 28} 32 [‘bob‘, ‘natasha‘, ‘hurry‘] {‘name‘: ‘hurry‘, ‘sex‘: ‘man‘, ‘age‘: 10} 33 [‘bob‘, ‘natasha‘, ‘hurry‘] 34 3 1818604672 35 3 1818604672 36 3 1818604672 37 3 1818604672
結果發現:在實例化的過程中,類本身做的屬性修改操作,不會對對象造成任何影響,所有的對象都不包含count屬性和obj_list屬性,都是通過類去調用的。
1 class Chinese: 2 country = ‘China‘ 3 language = ‘chinese‘ 4 def __init__(self,name,sex,age): 5 self.name=name 6 self.sex=sex 7 self.age=age 8 def sleep(self): 9 print(‘%s is eating‘ %self.name) 10 def work(self): 11 print(‘%s is working‘ %self.name) 12 p1=Chinese(‘bob‘,‘man‘,18) 13 p2=Chinese(‘natasha‘,‘woman‘,28) 14 # Chinese.work() #拋出TypeError 15 p1.work() 16 p2.work() 17 #輸出結果 18 bob is working 19 natasha is working
python基礎之面向對象編程介紹、類和對象