1. 程式人生 > >python基礎之面向對象編程介紹、類和對象

python基礎之面向對象編程介紹、類和對象

屬於 func 每次 基礎 lang 屬性字典 位置 需求 內部

面向對象變成介紹

面向過程編程

核心是過程(流水線式思維),過程即解決問題的步驟,面向過程的設計就好比精心設計好一條流水線,考慮周全什麽時候處理什麽東西。主要應用在一旦完成很少修改的地方,如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基礎之面向對象編程介紹、類和對象