Python基礎day-16[面向對象編程(未完)]
面向對象:
相對於面向過程編程來講,面向對象的擴展性比較強。但是同時帶來的問題是可控性差,面向對象編程不像面向過程那樣可以很精準的預測結果。面向對象程序一旦開始就由對象之間進行交互解決問題。
面向對象程序設計只是用來解決程序擴展性的。
什麽是對象:
舉一個例子:每個人都有自己特征和技能,那麽每個人就是一個對象。對象就是特征與技能的結合體。
什麽是類:
每個人都有自己獨有特征也有和別人同樣的技能或者特征。例如:基本每個人都會吃飯,都會睡覺,都會說話或者某兩個人眼睛都挺大。我們可以把這些共同的技能或者特征歸為一類。所以類就是一系列對象的共同特征與技能的結合體。
先有對象還是先有類:
在現實生活中,我們都知道只有一個新生事物誕生的時候,我們人類才能根據這個新生事物的特征去給它劃分類。所以在現實生活中是先有對象之後才有的類。然而在程序中不是這樣的,在Python中我們使用類來生成一個個對象。Python的類包含了這些對象共同的特征或者技能。
創建類:
class 不同於 def,如果不調用def定義的函數,那麽Python只會去定義,我們原來講過,函數分為定義階段和調用階段,定義階段只檢查語法是否正確。而class在定義的時候就會把class內部的指令都執行一遍。
#定義一個中國人 類
class Chinese: #class 類名: #一般類名都會首字母大寫 country= ‘china‘ #共同的國家 def use(self): #共同的技能 print(‘use chopsticks‘) #我們都會使用筷子 print(‘from chinese‘) #打印一段內容 執行結果: D:\Python\Python36-32\python.exe E:/Python/Test/t.py from chinese #發現class 在定義的時候會執行一遍內部的指令,不僅僅像定義函數那樣 Process finished with exit code 0
建立對象:
實例化的概念:從抽象的類生成對象的這一過程稱為實例化。
class Chinese: country = ‘china‘ def use(self): print(‘use chopsticks‘)
#假裝生成了兩個中國人(生成了兩個對象p1,p2) p1 = Chinese() #加括號運行的意思,這就是實例化。 p2 = Chinese()
上面的建立的兩個中國人,他們的特征和技能都一樣。但是每個人的還有不同的特征或者技能,例如:名字,年齡,工作等等,這時候我麽可以通過 __init__來給它填上去。
註:__init__函數不能有返回值,或者說返回值必須為None。
class Chinese: country = ‘china‘ def __init__(self,name,age,job): #定義一個init函數,self會自己把對象的名字拿過來傳給init函數的第一個參數(可自定義self的名字,但是不推薦),所以我們在定義三個形參,name,age,job。 self.name = name #這個翻譯過來就是 對象的名字 = 輸入的名字 #前面那個name跟後面那個name沒有關系的,下面同這個一樣的意思 self.age = age self.job = job def use(self): print(‘use chopsticks‘) #這時候我們就需要在原本的括號內加點東西了,為什麽這裏是三個參數,而不是四個參數(位置參數必須跟形參一一對應),上面說了self會自動找到對象的名字傳給init的第一個參數,所以我們只需傳後三個就行。 p1 = Chinese(‘ZhangSan‘,28,‘teacher‘) p2 = Chinese(‘LiSi‘,18,‘student‘) print(p1.__dict__) #使用 objectname.__dic__ 來查看對象的屬性信息,字典形式key為屬性名,value為屬性值。 print(p2.__dict__) 執行結果: D:\Python\Python36-32\python.exe E:/Python/Test/t.py {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘} #這裏我們能看見上面定義__init__時,裏面的self.name ... 都是屬性名。 {‘name‘: ‘LiSi‘, ‘age‘: 18, ‘job‘: ‘student‘} Process finished with exit code 0
查看類的屬性:
dir(類名):查出的是一個名字列表 類名.__dict__:查出的是一個字典,key為屬性名,value為屬性值 二:特殊的類屬性 類名.__name__# 類的名字(字符串) 類名.__doc__# 類的文檔字符串 類名.__base__# 類的第一個父類(在講繼承時會講) 類名.__bases__# 類所有父類構成的元組(在講繼承時會講) 類名.__dict__# 類的字典屬性 類名.__module__# 類定義所在的模塊 類名.__class__# 實例對應的類(僅新式類中)
類/對象的修改:
class Chinese: country = ‘china‘ def __init__(self,name,age,job): self.name = name self.age = age self.job = job def use(self): print(‘use chopsticks‘) return ‘a‘ p1 = Chinese(‘ZhangSan‘,28,‘teacher‘) p2 = Chinese(‘LiSi‘,18,‘student‘) Chinese.name = ‘abc‘ #向類添加屬性 p1.sex = ‘man‘ #向對象添加屬性 p2.sex = ‘woman‘ print(p1.__dict__) #查看對象的屬性(沒有公共屬性)返回的是字典形式 key是屬性名,value是屬性值 print(p2.__dict__) print(Chinese.__dict__) #查看的是類的屬性 del p1.sex #刪除對象的屬性 del Chinese.name #刪除類的屬性 print(p1.__dict__) print(Chinese.__dict__) 執行結果: #紅色結果為刪除某一屬性之後的屬性信息 D:\Python\Python36-32\python.exe E:/Python/Test/t.py {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘, ‘sex‘: ‘man‘} {‘name‘: ‘LiSi‘, ‘age‘: 18, ‘job‘: ‘student‘, ‘sex‘: ‘woman‘} {‘__module__‘: ‘__main__‘, ‘country‘: ‘china‘, ‘__init__‘: <function Chinese.__init__ at 0x02A938A0>, ‘use‘: <function Chinese.use at 0x02A937C8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Chinese‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Chinese‘ objects>, ‘__doc__‘: None, ‘name‘: ‘abc‘} {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘} {‘__module__‘: ‘__main__‘, ‘country‘: ‘china‘, ‘__init__‘: <function Chinese.__init__ at 0x02A938A0>, ‘use‘: <function Chinese.use at 0x02A937C8>, ‘__dict__‘: <attribute ‘__dict__‘ of ‘Chinese‘ objects>, ‘__weakref__‘: <attribute ‘__weakref__‘ of ‘Chinese‘ objects>, ‘__doc__‘: None}
對象去修改類中的不可變數據和可變數據對比:
class Chinese: list_1 = [] count = 0 country = ‘china‘ def __init__(self,name,age,job): self.name = name self.age = age self.job = job self.list_1.append(name) #每實例化一次,對象就會把自己的name信息加入列表 self.count += 1 #每實例化一次,對象就會把count 加 1 def use(self): print(‘use chopsticks‘) return ‘a‘ p1 = Chinese(‘ZhangSan‘,28,‘teacher‘) p2 = Chinese(‘LiSi‘,18,‘student‘) p3 = Chinese(‘Huang‘,20,‘student‘) print(p1.list_1,p1.__dict__) #查看對象的list_1 信息和 對象的屬性信息 print(p2.list_1,p1.__dict__) print(p3.list_1,p3.__dict__) print(Chinese.list_1) #查看類的list_1信息
print(id(p1.list_1),‘P1 list_1‘) #查看 對象的list_1內存地址
print(id(Chinese.list_1),‘Chinese list_1‘) #查看 類的list_1內存地址
print(id(p1.count),p1.count) print(id(p2.count),p2.count) print(id(p3.count),p3.count) print(id(Chinese.count),Chinese.count)
#根據執行結果發現,發現每個對象的屬性中沒有list_1的屬性,但是多出來一個count屬性。我們查看了 類的list_1屬性跟count屬性發現了不同。 執行結果: D:\Python\Python36-32\python.exe E:/Python/Test/t.py [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘, ‘count‘: 1} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘, ‘count‘: 1} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘Huang‘, ‘age‘: 20, ‘job‘: ‘student‘, ‘count‘: 1} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] # <------:這裏發現類的list_1屬性值跟上面對象中的一致並且內存地址也一致。所以對於可變數據,在類中是可以被修改的。
51806496 P1 list_1
51806496 Chinese list_1 499930864 1 #P1 499930864 1 #P2 499930864 1 #P3 499930848 0 #類的 <----:這裏發現內存地址不同,並且count數值也不同。所以對於不可變的數據,對象又開辟了新的內存空間進行引用,是建立在對象中的,而不是類中。 Process finished with exit code 0
類修改自己的可變數據和不可變數據對比:
通過下面的測試,發現類自己修改自己的數據的時候在實例化的時候不會對 對象造成任何影響,都是通過類去調用。
class Chinese: list_1 = [] count = 0 country = ‘china‘ def __init__(self,name,age,job): self.name = name self.age = age self.job = job Chinese.list_1.append(name) #每次實例化 類就會把實例化的對象的name加入列表 Chinese.count += 1 #每次實例化 類都會把count 加 1 def use(self): print(‘use chopsticks‘) return ‘a‘ p1 = Chinese(‘ZhangSan‘,28,‘teacher‘) p2 = Chinese(‘LiSi‘,18,‘student‘) p3 = Chinese(‘Huang‘,20,‘student‘) print(p1.list_1,p1.__dict__) print(p2.list_1,p1.__dict__) print(p3.list_1,p3.__dict__) print(Chinese.list_1) print(id(p1.list_1),‘P1 list_1‘) print(id(Chinese.list_1),‘Chinese list_1‘) print(id(p1.count),p1.count) print(id(p2.count),p2.count) print(id(p3.count),p3.count) print(id(Chinese.count),Chinese.count) 執行結果: D:\Python\Python36-32\python.exe E:/Python/Test/t.py [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘ZhangSan‘, ‘age‘: 28, ‘job‘: ‘teacher‘} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] {‘name‘: ‘Huang‘, ‘age‘: 20, ‘job‘: ‘student‘} [‘ZhangSan‘, ‘LiSi‘, ‘Huang‘] 45973792 P1 list_1 45973792 Chinese list_1 493180688 3 493180688 3 493180688 3 493180688 3 Process finished with exit code 0
Python基礎day-16[面向對象編程(未完)]