【我要學python】面向物件系統學習
第一節:初識類的定義和呼叫 c1.py
#類 = 面向物件
#類 最基本作用:封裝
#類中不僅可以定義變數 還可以定義函式等等,例:
1 class student( ): 2name = ' ' 3age = 0 4 5def print_file(): 6pass
#類的例項化
1 s = student()
#呼叫類方法
2 s.print_file()
#類中編寫的函式與普通編寫的函式有區別——self ,例:
class student( ): name = ' ' age = 0 def print_file(self):#要呼叫類自身的變數需要加上self print('name:' + self.name) print('age:' + str(self.age)) #print_file() 報錯 類負責定義封裝 不要在類裡呼叫
第二節:函式與方法的區別 c2.py
#如何在另外一個模組使用我們的類
1 #c2.py呼叫c1.py的類 2 from c1 import student 3 s = student() 4 s.print_file()
#方法和函式的區別
多數情況下,c,c++把此概念稱為函式;java,c#把此概念稱為方法。
方法:設計層面的稱謂
函式:程式執行,過程式的稱謂
也就是說面向物件更關心程式碼的設計
#類中的變數
變數:在類中被稱為資料成員
體現類的封裝性
第三節:類與物件 c3.py
#類和物件到底是什麼?它們有什麼關係?
類是現實世界或思維世界中實體在計算機中的反映, 它將資料以及這些資料上的操作封裝在一起
類和物件通過例項化關聯在一起
#類的設計在於 行為與特徵 的設計
1 class student( ): 2name = ' ' 3age = 0 4def do_homework(slef): 5print('homework') 6 7 #print_file 列印檔案行為屬於student主體明顯不太適合 ,做作業的方法屬於student方法沒毛病 8 9 class printer(): 10def print_file(self): 11print('name:' + self.name) 12print('age:' + str(self.age))
#類像一個印刷機,能夠通過模板做出各種各樣的物件。
通過student類(像一個模板模板)可以產生學生A,學生B...很多個物件,它們都有的特性是name和age
第四節:建構函式
#例項化
a = student( ) #用student這個模板來創造例項a
#建構函式的介紹:
class student(): def _init_(self):#建構函式 print('student') s1 = student() s1.__init__() #輸出 student student #有兩個student 原因是:建構函式是呼叫時python使其自動進行的 無需再呼叫一次 #注意:建構函式只能return None 也就是預設不寫return
#利用建構函式使物件例項化時多種多樣
class student(): name = ' ' age = 0 def __init__(self,name,age): name = name#這裡python自己知道左邊是變數 右邊是形參 是合法的 age = age s1 = student('大頭',18) #例項化的多樣性 print(s1.name) #輸出空值 是為什麼呢?!因為這裡列印的是類變數name print(student.name) #同樣輸出 空值
第四節,類變數和例項變數
#類變數和例項變數
類變數:與類關聯的變數
例項變數:和物件關聯在一起的
#用self完成例項變數的定義 def __init__(self,name,age): self.name = name self.age = age
class student(): name = '你的青'#類變數 age = 19 def __init__(self,name,age): self.name = name#例項變數 self.age = age#例項變數 s1 = student('大頭',19) print(s1.name) print(student.name) #輸出 大頭 你的青
第五節:類與物件的變數查詢順序
class student(): name = '你的青 ' age = 0 def __init__(self,name,age): name = name age = age s1 = student('大頭',18) print(s1.name) print(student.name) #輸出 你的青 你的青 #因為在外部呼叫時python首先尋找例項裡面查詢對應變數,沒有找到的話就會去類變數裡面尋找。
第六節:self與例項方法
class student(): name = '你的青 '#類變數 age = 0 def __init__(self,name,age): name = name age = ageprint(age)#訪問例項變數 最好是帶上self. print(name)#沒加self的讀取的只是形參變數. 這裡的age和name都是形參接收的值。 s1 = student('大頭',18) #輸出 18 大頭
#例項方法的特點即 方法第一個引數需要傳入self
第七節:在例項方法內部 中訪問例項變數與類變數
#總結已經學習的內容
#方法來定義我們的行為和特徵
class student(): sum1 = 0 def __init__(self,name,age): self.name = name self.age = age print(sum1) #輸出 'sum1' is not define 報錯
1 class student(): 2sum1 = 0 3 4def __init__(self,name,age): 5self.name = name 6self.age = age 7 8print(student.sum1) #在例項方法內訪問類變數方法一 9print(self.__class__.sum1) #在例項方法內訪問類變數方法二 10 11 #輸出 12 13 0 14 0
第八節:新方法——類方法
#類變數的作用
1 #例項方法操作類變數 2 3 class student(): 4sum1=0 5 6def __init__(self,name,age): 7self.name = name 8self.age = age 9self.__class__.sum1 += 1 10print("當前班級學生總數:" + str(self.__class__.sum1)) 11 12 s1 = student('小帥哥',18) 13 s2 = student('小仙女',18) 14 s1 = student('你的青',19) 15 16 #輸出 17 當前班級學生總數:1 18 當前班級學生總數:2 19 當前班級學生總數:3
#如何定義一個類方法
1 class student(): 2sum1 = 0 3 4def __init__(self,name,age): 5self.name = name 6self.age = age 7 8@classmethod# 增加一個裝飾器 9def plus_sum(cls):# 預設cls 即class簡寫 也可以用self 10cls.sum1 += 1 11print("當前班級學生總數:" + str(cls.sum1)) 12 13 s1 = student('小帥哥', 18) 14 student.plus_sum() 15 s2 = student('小仙女', 18) 16 student.plus_sum() 17 s1 = student('你的青', 19) 18 student.plus_sum() 19 20 #輸出 21 當前班級學生總數:1 22 當前班級學生總數:2 23 當前班級學生總數:3
#為什麼要這樣做?規範!和student例項物件無關的東西,例如班級總人數就可以放在類方法裡
第九節:新方法——靜態方法
class student(): sum1 = 0 def __init__(self,name,age): self.name = name self.age = age @classmethod# 增加一個類裝飾器 def plus_sum(cls):# 預設cls 即class簡寫 也可以用self cls.sum1 += 1 print("當前班級學生總數:" + str(cls.sum1)) @staticmethod# 增加一個靜態裝飾器 def add(x,y): print('this is a static method') s1 = student s1.add(1,2) student.add(1,2) #輸出 this is a static method this is a static method #靜態方法不同點 函式定義時引數不需要寫self 呼叫時就要寫class名 #儘量少用靜態方法 和類關聯不大
第十節:成員可見性:公開和私有
#探討python下面變數,方法的可見性
#類的外部 類的內部
class student(): sum1 = 0 def __init__(self,name,age): self.name = name self.age = age self.score = 0 def marking(self,score):#python提倡所有對於類下面變數的更改通過方法來完成 if score < 0:#(粉色程式碼)這樣規則和機制的靈活性很就高 return '分數不能為負' self.score = score print(self.name + '同學本次考試分數為:' + str(self.score)) @classmethod# 增加一個類裝飾器 def plus_sum(cls):# 預設cls 即class簡寫 也可以用self cls.sum1 += 1 print("當前班級學生總數:" + str(cls.sum1)) @staticmethod# 增加一個靜態裝飾器 def add(x,y): print('this is a static method') s1 = student('青', 20) s1.marking(60) result = s1.marking(-6) print(result) #輸出 青同學本次考試分數為:60 分數不能為負
#如何使類的變數或者方法私有化(即類的外部無法訪問呼叫)
#在其他很多語言中,對類的範圍是有明確要求的,private代表私有 public代表公開
#在python中,私有化只需要新增雙下劃線
class student(): def __init__(self,name,age): self.name = name self.age = age def __marking(self,score):#這裡添加了雙下劃線 if score < 0: return '分數不能為負' self.score = score print(self.name + '同學本次考試分數為:' + str(self.score)) s1 = student('青',20) s1.__marking(59) #輸出 報錯 此時__marking已經私有化 AttributeError: 'student' object has no attribute '__marking'
#建構函式屬於python特有函式,自動執行,並且只能返回None,不過它可以從外部呼叫;小技巧:函式名的前後都新增雙下劃線的時候,python不會認為它是private。
第十一節:沒有什麼是不能訪問
class student(): def __init__(self, name, age): self.name = name self.age = age self.__score = 0# 這裡設定了例項的私有變數 def marking(self, score): if score < 0: return '分數不能為負' self.__score = score print(self.name + '同學本次考試分數為:' + str(self.__score)) s1 = student('青', 20) s1.__score = 1 print(s1.__score)# 嘗試輸出私有變數 #輸出 1 #因為動態語言強行賦值,此時的__score並不是私有變數student_score,可以通過print(s1.__dict__)驗證
1 class student(): 2def __init__(self, name, age): 3self.name = name 4self.age = age 5self.__score = 0# 這裡設定了例項的私有變數 6def marking(self, score): 7if score < 0: 8return '分數不能為負' 9self.__score = score 10print(self.name + '同學本次考試分數為:' + str(self.__score)) 11 s1 = student('青', 20) 12 s1.__score = 1 13 print(s1.__score)# 嘗試輸出 14 15 s2 = student('傻',18) 16 print(s2.__score) # 嘗試輸出私有變數 17 18 #輸出 報錯 因為這裡沒有強制賦值 所以是直接想輸出私有變數 19 AttributeError: 'student' object has no attribute 'student__score' 20 21 #其實python只是把私有變數改了名字而已 __score在裡面就被改為_student__socre 22 23 class student(): 24def __init__(self, name, age): 25self.name = name 26self.age = age 27self.__score = 0# 這裡設定了例項的私有變數 28def marking(self, score): 29if score < 0: 30return '分數不能為負' 31self.__score = score 32print(self.name + '同學本次考試分數為:' + str(self.__score)) 33 s1 = student('青', 20) 34 s1.__score = 1 35 print(s1.__score)# 嘗試輸出 36 37 s2 = student('傻',18) 38 print(s2._student__score) # 嘗試輸出私有變數 39 40 #輸出正常 41 1 42 0
第十二節:面對物件三大 特性之 繼承性
#回顧之前所學內容
#類由 類的特徵 行為 方法 等等組成 繼承性就是為了避免我們重複地寫程式碼
#例如 student類的父類還有human類
1 #c5.py 2 from c6 import Human#標準的繼承方法 3 class student(Human):#標準的繼承方法 4sum = 0 5def __init__(self,name,age): 6self.name = name 7self.age = age 8self.score = 0 9self.__class__.sum += 1 10 11def do_homework(self) 12print('english homework') 13 14 #c6.py 15 class Human(): 16pass
#深化程式碼,使其有成為意義的繼承
1 #c6.py 2 class Human(): 3def __init__(self,name,age): 4self.name = name 5self.age = age 6 7def get_name(self): 8print(self.name) 9 10 #c5.py 11 from c6 import Human#標準的繼承方法 12 class student(Human):#標準的繼承方法 13def do_homework(self): 14print('english homework') 15 16 17 s1 = student('你的青',20) 18 s1.get_name() 19 print(s1.name) 20 print(s1.age) 21 22 #輸出 23 你的青 24 你的青 25 20
#大多語言只能單繼承,python的多繼承功能有很大的利用空間
#c6.py class Human(): sum = 0 def __init__(self,name,age): self.name = name self.age = age def get_name(self): print(self.name) # c5.py from c6 import Human# 標準的繼承方法 class student(Human):# 標準的繼承方法 def __init__(self,school,name,age): self.school = school Human.__init__(self,name,age)#呼叫父類的建構函式 從子類中傳入父類 靈活的python通過Human類呼叫一個例項方法時 需要加self s1 = student('人民路','你的青',20) print(s1.school) print(s1.name) print(s1.age) #輸出 人民路 你的青 20
#呼叫父類的建構函式還有第二種常用的方法:
#c6.py class Human(): sum = 0 def __init__(self,name,age): self.name = name self.age = age def get_name(self): print(self.name) # c5.py from c6 import Human# 標準的繼承方法 class student(Human):# 標準的繼承方法 def __init__(self,school,name,age): self.school = school super(student,self).__init__(name,age)#呼叫父類的建構函式 這種方法為常用的方法 如果父類名有改變的話不會影響到此方法 s1 = student('人民路','你的青',20) print(s1.school) print(s1.name) print(s1.age) #輸出 人民路 你的青 20
#當父類和子類出現同名方法時,python會首先呼叫子類的方法
#如果想呼叫父類的方法 同樣用到super函式呼叫父類函式
c6.py class Human(): sum = 0 def __init__(self,name,age): self.name = name self.age = age def do_homework(self): print('chinese homework') # c5.py from c6 import Human# 標準的繼承方法 class student(Human):# 標準的繼承方法 def __init__(self,school,name,age): self.school = school super(student,self).__init__(name,age) def do_homework(self): super(Student,self).do_homework() print('english homework') #呼叫父類的建構函式 這種方法為常用的方法 如果父類名有改變的話不會影響到此方法 s1 = student('人民路','你的青',20) s1.do_homework() #輸出 chinese homework english homework