第三章 面向對象及相關
- 編程思想
1 ''' 2 面向過程:核心是過程二字,過程指的是解決問題的步驟,設計一條流水線,機械式的思維方式 3 優點:複雜的問題流程化,進而簡單化 4 缺點:可擴展性差 5 ''' 6 7 import json 8 import re 9 def interactive(): 10 name=input('>>: ').strip() 11 pwd=input('>>: ').strip() 12 email=input('>> ').strip() 13 return { 14 'name':name, 15 'pwd':pwd, 16 'email':email 17 } 18 19 def check(user_info): 20 is_valid=True 21 22 if len(user_info['name']) == 0: 23 print('用戶名不能為空') 24 is_valid=False 25 26 if len(user_info['pwd']) < 6: 27 print('密碼不能少於6位') 28 is_valid=False 29 30 if not re.search(r'@.*?\.com$',user_info['email']): 31 print('郵箱格式不合法') 32 is_valid=False 33 34 return { 35 'is_valid':is_valid, 36 'user_info':user_info 37 } 38 39 def register(check_info): 40 if check_info['is_valid']: 41 with open('db.json','w',encoding='utf-8') as f: 42 json.dump(check_info['user_info'],f) 43 44 45 46 def main(): 47 user_info=interactive() 48 49 check_info=check(user_info) 50 51 register(check_info) 52 53 if __name__ == '__main__': 54 main()
面向過程編程
1 ''' 2 面向對象:核心就是對象二字,對象就是特徵與技能的結合體 3 優點:可擴展性強 4 缺點:編程複雜度高 5 應用場景:用戶需求經常變化,互聯網應用,遊戲,企業內部應用 6 7 8 類就是一系列對象相似的特徵與技能的結合體 9 強調:站在不同的角度,得到的分類是不一樣的 10 11 在現實世界中:一定先有對象,後有類 12 在程式中:一定得先定義類,後調用類來產生對象 13 14 站在路飛學院的角度,大家都是學生 15 16 在現實世界中: 17 對象1:王二丫 18 特徵: 19 學校='luffycity' 20 名字='王二丫' 21 性別='女' 22 年齡=18 23 技能: 24 學習 25 吃飯 26 睡覺 27 28 對象2:李三炮 29 特徵: 30 學校='luffycity' 31 名字='李三炮' 32 性別='男' 33 年齡=38 34 技能: 35 學習 36 吃飯 37 睡覺 38 39 對象3:張鐵蛋 40 特徵: 41 學校='luffycity' 42 名字='張鐵蛋' 43 性別='男' 44 年齡=48 45 技能: 46 學習 47 吃飯 48 睡覺 49 50 總結現實中路飛學院的學生類: 51 相似的特徵 52 學校='luffycity' 53 54 相似的技能 55 學習 56 吃飯 57 睡覺 58 59 60 ''' 61 62 #先定義類 63 class LuffyStudent: 64 school='luffycity' 65 66 def learn(self): 67 print('is learning') 68 69 def eat(self): 70 print('is sleeping') 71 72 73 #後產生對象 74 stu1=LuffyStudent() 75 stu2=LuffyStudent() 76 stu3=LuffyStudent() 77 78 print(stu1) 79 print(stu2) 80 print(stu3)
面向對象編程
- 類的使用(一)
1 先定義類 2 class LuStudent: 3 school='luffycity' #數據屬性 4 5 6 def learn(self): #函數屬性 7 print('is learning') 8 9 def eat(self): #函數屬性 10 print('is sleeping') 11 12 13 #查看類的名稱空間 14 #print(LuStudent.__dict__) 15 #print(LuStudent.__dict__['school']) 16 #print(LuStudent.__dict__['learn']) 17 18 19 #查 20 #print(LuffyStudent.school) #LuffyStudent.__dict__['school'] 21 #print(LuffyStudent.learn) #LuffyStudent.__dict__['learn'] 22 23 #增 24 LuffyStudent.county='China' 25 # print(LuffyStudent.__dict__) 26 print(LuffyStudent.county) 27 28 #刪 29 del LuffyStudent.county 30 31 #改 32 LuffyStudent.school='Lucity'
類的基本使用
1 #__init__方法用來為對象訂製對象自己獨有的特徵 2 class LuStudent: 3 school='lucity' 4 5 # stu1, '王二丫', '女', 18 6 def __init__(self,name,sex,age): 7 self.Name=name 8 self.Sex=sex 9 self.Age=age 10 11 #stu1.Name='王二丫' 12 #stu1.Sex='女' 13 #stu1.Age=18 14 15 def learn(self): 16 print('is learning') 17 18 def eat(self): 19 print('is sleeping') 20 21 22 #後產生對象 23 stu1=LuStudent('王二丫','女',18) #LuStudent.__init__(stu1,'王二丫','女',18) 24 25 #加上__init__方法後,實例化的步驟 26 # 1、先產生一個空對象stu1 27 # 2、LuStudent.__init__(stu1,'王二丫','女',18) 28 29 30 #查 31 print(stu1.__dict__) 32 #print(stu1.Name) 33 #print(stu1.Sex) 34 #print(stu1.Age) 35 36 #改 37 # stu1.Name='李二丫' 38 # print(stu1.__dict__) 39 # print(stu1.Name) 40 41 42 #刪除 43 # del stu1.Name 44 # print(stu1.__dict__) 45 # 46 # #增 47 # stu1.class_name='python開發' 48 # print(stu1.__dict__) 49 # 50 # 51 # stu2=LuStudent('李三炮','男',38) #Lucity.__init__(stu2,'李三炮','男',38) 52 # print(stu2.__dict__) 53 # print(stu2.Name) 54 # print(stu2.Age) 55 # print(stu2.Sex) 56 57 # 類的屬性查找 58 ''' 59 在現實世界中: 60 對象1:王二丫 61 特徵: 62 學校='luffycity' 63 名字='王二丫' 64 性別='女' 65 年齡=18 66 技能: 67 學習 68 吃飯 69 睡覺 70 71 對象2:李三炮 72 特徵: 73 學校='luffycity' 74 名字='李三炮' 75 性別='男' 76 年齡=38 77 技能: 78 學習 79 吃飯 80 睡覺 81 82 對象3:張鐵蛋 83 特徵: 84 學校='luffycity' 85 名字='張鐵蛋' 86 性別='男' 87 年齡=48 88 技能: 89 學習 90 吃飯 91 睡覺 92 93 總結現實中路飛學院的學生類: 94 相似的特徵 95 學校='luffycity' 96 97 相似的技能 98 學習 99 吃飯 100 睡覺 101 102 ''' 103 x='global' 104 class LuStudent: 105 school='lucity' 106 107 def __init__(self,name,sex,age): 108 self.Name=name 109 self.Sex=sex 110 self.Age=age 111 112 #stu1.Name='王二丫' 113 #stu1.Sex='女' 114 #stu1.Age=18 115 116 def learn(self,x): 117 print('%s is learning %s' %(self.Name,x)) 118 119 def eat(self): 120 print('%s is sleeping' %self.Name) 121 122 123 #後產生對象 124 stu1=LuStudent('王二丫','女',18) 125 stu2=LuStudent('李三炮','男',38) 126 stu3=LuStudent('張鐵蛋','男',48) 127 # print(stu1.__dict__) 128 # print(stu2.__dict__) 129 # print(stu3.__dict__) 130 131 132 133 #對象:特徵與技能的結合體 134 #類:類是一系列對象相似的特徵與相似的技能的結合體 135 136 137 138 #類中的數據屬性:是所以對象共有的 139 # print(LuStudent.school,id(LuStudent.school)) 140 # 141 # print(stu1.school,id(stu1.school)) 142 # print(stu2.school,id(stu2.school)) 143 # print(stu3.school,id(stu3.school)) 144 145 146 #類中的函數屬性:是綁定給對象使用的,綁定到不同的對象是不同的綁定方法,對象調用綁定方式時,會把對象本身當作第一個傳入,傳給self 147 148 # print(LuStudent.learn) 149 # LuffyStudent.learn(stu1) 150 # LuffyStudent.learn(stu2) 151 # LuffyStudent.learn(stu3) 152 153 154 # print(stu1.learn) 155 # stu1.learn(1) #learn(stu1,1) 156 # print(stu2.learn) 157 # print(stu3.learn) 158 159 # 補充 160 #python一切皆對象,在python3里統一類類與類型的概念 161 162 163 # print(type([1,2])) 164 165 166 # print(list) 167 168 class LuStudent: 169 school='lucity' 170 171 def __init__(self,name,sex,age): 172 self.Name=name 173 self.Sex=sex 174 self.Age=age 175 176 #stu1.Name='王二丫' 177 #stu1.Sex='女' 178 #stu1.Age=18 179 180 def learn(self,x): 181 print('%s is learning %s' %(self.Name,x)) 182 183 def eat(self): 184 print('%s is sleeping' %self.Name) 185 186 187 # print(LuffyStudent) 188 189 190 l1=[1,2,3] #l=list([1,2,3]) 191 l2=[] #l=list([1,2,3]) 192 # l1.append(4) #list.append(l1,4) 193 list.append(l1,4) 194 print(l1) 195 196 小結 197 class Chinese: 198 county='China' 199 def __init__(self,name,age,sex): 200 self.name=name 201 self.age=age 202 self.sex=sex 203 def eat(self): 204 print('%s is eating' %self.name) 205 206 p1=Chinese('eg',18,'male') 207 p2=Chinese('al',38,'female') 208 p3=Chinese('wpq',48,'female') 209 210 # print(p1.county) 211 # print(p2.county) 212 # print(p3.county) 213 214 p1.eat() 215 p2.eat() 216 p3.eat()
類的__init__,&屬性查找..
1 ''' 2 練習1:編寫一個學生類,產生一堆學生對象, (5分鐘) 3 4 要求: 5 6 有一個計數器(屬性),統計總共實例了多少個對象 7 ''' 8 9 class Student: 10 school='luffycity' 11 count=0 12 13 def __init__(self,name,age,sex): 14 self.name=name 15 self.age=age 16 self.sex=sex 17 # self.count+=1 18 Student.count+=1 19 20 def learn(self): 21 print('%s is learing' %self.name) 22 23 24 stu1=Student('alex','male',38) 25 stu2=Student('jinxing','female',78) 26 stu3=Student('egon','male',18) 27 28 # 29 # print(Student.count) 30 # print(stu1.count) 31 # print(stu2.count) 32 # print(stu3.count) 33 # print(stu1.__dict__) 34 # print(stu2.__dict__) 35 # print(stu3.__dict__) 36 37 38 39 ''' 40 練習2:模仿LoL定義兩個英雄類, (10分鐘) 41 42 要求: 43 44 英雄需要有昵稱、攻擊力、生命值等屬性; 45 實例化出兩個英雄對象; 46 英雄之間可以互毆,被毆打的一方掉血,血量小於0則判定為死亡。 47 ''' 48 49 class Garen: 50 camp='Demacia' 51 52 def __init__(self,nickname,life_value,aggresivity): 53 self.nickname=nickname 54 self.life_value=life_value 55 self.aggresivity=aggresivity 56 57 def attack(self,enemy): 58 enemy.life_value-=self.aggresivity 59 #r1.life_value-=g1.aggresivity 60 61 class Riven: 62 camp = 'Noxus' 63 64 def __init__(self, nickname, life_value, aggresivity): 65 self.nickname = nickname 66 self.life_value = life_value 67 self.aggresivity = aggresivity 68 69 def attack(self, enemy): 70 enemy.life_value -= self.aggresivity 71 72 g1=Garen('草叢倫',100,30) 73 74 r1=Riven('可愛的銳雯雯',80,50) 75 76 print(r1.life_value) 77 g1.attack(r1) 78 print(r1.life_value)
練習
1 # class ParentClass1: 2 # pass 3 # 4 # class ParentClass2: 5 # pass 6 # 7 # class SubClass1(ParentClass1): 8 # pass 9 # 10 # class SubClass2(ParentClass1,ParentClass2): 11 # pass 12 # 13 # print(SubClass1.__bases__) 14 # print(SubClass2.__bases__) 15 16 17 18 # class Hero: 19 # x=3 20 # def __init__(self,nickname,life_value,aggresivity): 21 # self.nickname=nickname 22 # self.life_value=life_value 23 # self.aggresivity=aggresivity 24 # def attack(self,enemy): 25 # enemy.life_value-=self.aggresivity 26 # 27 # class Garen(Hero): 28 # # x=2 29 # pass 30 31 # class Riven(Hero): 32 # pass 33 34 35 # g1=Garen('剛們',29,30) 36 # # print(g1.nickname,g1.life_value,g1.aggresivity) 37 # # g1.x=1 38 # 39 # print(g1.x) 40 41 42 43 #屬性查找小練習 44 class Foo: 45 def f1(self): 46 print('from Foo.f1') 47 48 def f2(self): 49 print('from Foo.f2') 50 self.f1() #b.f1() 51 52 class Bar(Foo): 53 def f1(self): 54 print('from Bar.f1') 55 56 b=Bar() 57 # print(b.__dict__) 58 b.f2()
類的繼承
1 #1、新式類 2 3 #2、經典類 4 5 #在python2中-》經典類:沒有繼承object的類,以及它的子類都稱之為經典類 6 # 7 # class Foo: 8 # pass 9 # 10 # class Bar(Foo): 11 # pass 12 # 13 # 14 # #在python2中-》新式類:繼承object的類,以及它的子類都稱之為新式類 15 # class Foo(object): 16 # pass 17 # 18 # class Bar(Foo): 19 # pass 20 21 22 #在python3中-》新式類:一個類沒有繼承object類,默認就繼承object 23 24 # class Foo(): 25 # pass 26 # print(Foo.__bases__) 27 28 29 #驗證多繼承情況下的屬性查找 30 31 class A: 32 # def test(self): 33 # print('from A') 34 pass 35 36 class B(A): 37 # def test(self): 38 # print('from B') 39 pass 40 41 class C(A): 42 # def test(self): 43 # print('from C') 44 pass 45 46 class D(B): 47 # def test(self): 48 # print('from D') 49 pass 50 51 class E(C): 52 # def test(self): 53 # print('from E') 54 pass 55 56 class F(D,E): 57 # def test(self): 58 # print('from F') 59 pass 60 61 62 #F,D,B,E,C,A 63 64 print(F.mro()) 65 # f=F() 66 # f.test()
繼承的實現原理
1 #在子類派生出的新的方法中重用父類的方法,有兩種實現方式 2 #方式一:指名道姓(不依賴繼承) 3 # class Hero: 4 # def __init__(self,nickname,life_value,aggresivity): 5 # self.nickname=nickname 6 # self.life_value=life_value 7 # self.aggresivity=aggresivity 8 # def attack(self,enemy): 9 # enemy.life_value-=self.aggresivity 10 # 11 # 12 # class Garen(Hero): 13 # camp='Demacia' 14 # 15 # def attack(self,enemy): 16 # Hero.attack(self,enemy) #指名道姓 17 # print('from Garen Class') 18 # 19 # class Riven(Hero): 20 # camp='Noxus' 21 # 22 # 23 # g=Garen('草叢倫',100,30) 24 # r=Riven('銳雯雯',80,50) 25 # 26 # print(r.life_value) 27 # g.attack(r) 28 # print(r.life_value) 29 30 31 32 33 # class Hero: 34 # def __init__(self,nickname,life_value,aggresivity): 35 # self.nickname=nickname 36 # self.life_value=life_value 37 # self.aggresivity=aggresivity 38 # def attack(self,enemy): 39 # enemy.life_value-=self.aggresivity 40 41 42 # class Garen(Hero): 43 # camp='Demacia' 44 # 45 # def __init__(self,nickname,life_value,aggresivity,weapon): 46 # # self.nickname=nickname 47 # # self.life_value=life_value 48 # # self.aggresivity=aggresivity 49 # Hero.__init__(self,nickname,life_value,aggresivity) 50 # 51 # self.weapon=weapon 52 # 53 # def attack(self,enemy): 54 # Hero.attack(self,enemy) #指名道姓 55 # print('from Garen Class') 56 # 57 # 58 # g=Garen('草叢倫',100,30,'金箍棒') 59 # 60 # print(g.__dict__) 61 62 63 64 65 #方式二:super() (依賴繼承) 66 # class Hero: 67 # def __init__(self,nickname,life_value,aggresivity): 68 # self.nickname=nickname 69 # self.life_value=life_value 70 # self.aggresivity=aggresivity 71 # def attack(self,enemy): 72 # enemy.life_value-=self.aggresivity 73 # 74 # 75 # class Garen(Hero): 76 # camp='Demacia' 77 # 78 # def attack(self,enemy): 79 # super(Garen,self).attack(enemy) #依賴繼承 80 # print('from Garen Class') 81 # 82 # class Riven(Hero): 83 # camp='Noxus' 84 # 85 # 86 # g=Garen('草叢倫',100,30) 87 # r=Riven('銳雯雯',80,50) 88 # 89 # g.attack(r) 90 # print(r.life_value) 91 92 93 # class Hero: 94 # def __init__(self,nickname,life_value,aggresivity): 95 # self.nickname=nickname 96 # self.life_value=life_value 97 # self.aggresivity=aggresivity 98 # def attack(self,enemy): 99 # enemy.life_value-=self.aggresivity 100 # 101 # 102 # class Garen(Hero): 103 # camp='Demacia' 104 # 105 # def __init__(self,nickname,life_value,aggresivity,weapon): 106 # # self.nickname=nickname 107 # # self.life_value=life_value 108 # # self.aggresivity=aggresivity 109 # 110 # # super(Garen,self).__init__(nickname,life_value,aggresivity) 111 # super().__init__(nickname,life_value,aggresivity) 112 # self.weapon=weapon 113 # 114 # def attack(self,enemy): 115 # Hero.attack(self,enemy) #指名道姓 116 # print('from Garen Class') 117 # 118 # 119 # g=Garen('草叢倫',100,30,'金箍棒') 120 # 121 # print(g.__dict__) 122 123 124 125 126 127 128 129 130 class A: 131 def f1(self): 132 print('from A') 133 super().f1() 134 135 136 class B: 137 def f1(self): 138 print('from B') 139 140 class C(A,B): 141 pass 142 143 144 print(C.mro()) 145 #[<class '__main__.C'>, 146 # <class '__main__.A'>, 147 # <class '__main__.B'>, 148 # <class 'object'>] 149 150 151 c=C() 152 c.f1()
子類中重用父類屬性
1 class People: 2 school='luffycity' 3 4 def __init__(self,name,age,sex): 5 self.name=name 6 self.age=age 7 self.sex=sex 8 9 10 class Teacher(People): 11 def __init__(self,name,age,sex,level,salary,): 12 super().__init__(name,age,sex) 13 14 self.level=level 15 self.salary=salary 16 17 18 def teach(self): 19 print('%s is teaching' %self.name) 20 21 22 class Student(People): 23 def __init__(self, name, age, sex, class_time,): 24 super().__init__(name,age,sex) 25 26 self.class_time=class_time 27 28 def learn(self): 29 print('%s is learning' % self.name) 30 31 class Course: 32 def __init__(self,course_name,course_price,course_period): 33 self.course_name = course_name 34 self.course_price = course_price 35 self.course_period = course_period 36 37 def tell_info(self): 38 print('課程名<%s> 課程價錢<%s> 課程周期<%s>' %(self.course_name,self.course_price,self.course_period)) 39 40 class Date: 41 def __init__(self,year,mon,day): 42 self.year=year 43 self.mon=mon 44 self.day=day 45 46 def tell_info(self): 47 print('%s-%s-%s' %(self.year,self.mon,self.day)) 48 49 # teacher1=Teacher('alex',18,'male',10,3000,) 50 # teacher2=Teacher('egon',28,'male',30,3000,) 51 # python=Course('python',3000,'3mons') 52 # linux=Course('linux',2000,'4mons') 53 54 # print(python.course_name) 55 56 # teacher1.course=python 57 # teacher2.course=python 58 59 # print(python) 60 # print(teacher1.course) 61 # print(teacher2.course) 62 # print(teacher1.course.course_name) 63 # print(teacher2.course.course_name) 64 # teacher1.course.tell_info() 65 66 # student1=Student('張三',28,'female','08:30:00') 67 # student1.course1=python 68 # student1.course2=linux 69 70 # student1.course1.tell_info() 71 # student1.course2.tell_info() 72 # student1.courses=[] 73 # student1.courses.append(python) 74 # student1.courses.append(linux) 75 76 77 78 student1=Student('張三',28,'female','08:30:00') 79 d=Date(1988,4,20) 80 python=Course('python',3000,'3mons') 81 82 83 student1.birh=d 84 student1.birh.tell_info() 85 86 student1.course=python 87 88 student1.course.tell_info()
組合
1 import abc 2 3 class Animal(metaclass=abc.ABCMeta): #只能被繼承,不能被實例化 4 all_type='animal' 5 6 @abc.abstractmethod 7 def run(self): 8 pass 9 10 @abc.abstractmethod 11 def eat(self): 12 pass 13 14 # animal=Animal() 15 16 17 class People(Animal): 18 def run(self): 19 print('people is running') 20 21 def eat(self): 22 print('people is eating') 23 24 class Pig(Animal): 25 def run(self): 26 print('people is walking') 27 28 def eat(self): 29 print('people is eating') 30 31 class Dog(Animal): 32 def run(self): 33 print('people is walking') 34 35 def eat(self): 36 print('people is eating') 37 38 39 # peo1=People() 40 # pig1=Pig() 41 # dog1=Dog() 42 # # 43 # # 44 # peo1.eat() 45 # pig1.eat() 46 # dog1.eat() 47 # 48 # print(peo1.all_type)
抽象類(metaclass=abc.ABCMeta)
1 #多態:同一類事物的多種形態 2 import abc 3 class Animal(metaclass=abc.ABCMeta): #同一類事物:動物 4 @abc.abstractmethod 5 def talk(self): 6 pass 7 8 class People(Animal): #動物的形態之一:人 9 def talk(self): 10 print('say hello') 11 12 class Dog(Animal): #動物的形態之二:狗 13 def talk(self): 14 print('say wangwang') 15 16 class Pig(Animal): #動物的形態之三:豬 17 def talk(self): 18 print('say aoao') 19 20 class Cat(Animal): 21 def talk(self): 22 print('say miamiao') 23 24 #多態性:指的是可以在不考慮對象的類型的情況下而直接使用對象 25 peo1=People() 26 dog1=Dog() 27 pig1=Pig() 28 cat1=Cat() 29 30 # peo1.talk() 31 # dog1.talk() 32 # pig1.talk() 33 34 def func(animal): 35 animal.talk() 36 37 38 func(peo1) 39 func(pig1) 40 func(dog1) 41 func(cat1)
多態與多態性
1 # class A: 2 # __x=1 #_A__x=1 3 # 4 # def __init__(self,name): 5 # self.__name=name #self._A__name=name 6 # 7 # def __foo(self): #def _A__foo(self): 8 # print('run foo') 9 # 10 # def bar(self): 11 # self.__foo() #self._A__foo() 12 # print('from bar') 13 14 # print(A.__dict__) 15 # print(A.__x) 16 # print(A.__foo) 17 18 # a=A('egon') 19 # a._A__foo() 20 # a._A__x 21 22 # print(a.__name) #a.__dict__['__name'] 23 # print(a.__dict__) 24 25 # a.bar() 26 27 ''' 28 這種變形的特點: 29 1、在類外部無法直接obj.__AttrName 30 2、在類內部是可以直接使用:obj.__AttrName 31 3、子類無法覆蓋父類__開頭的屬性 32 ''' 33 34 # class Foo: 35 # def __func(self): #_Foo__func 36 # print('from foo') 37 # 38 # 39 # class Bar(Foo): 40 # def __func(self): #_Bar__func 41 # print('from bar') 42 43 # b=Bar() 44 # b.func() 45 46 47 48 # class B: 49 # __x=1 50 # 51 # def __init__(self,name): 52 # self.__name=name #self._B__name=name 53 54 55 #驗證問題一: 56 # print(B._B__x) 57 58 #驗證問題二: 59 # B.__y=2 60 # print(B.__dict__) 61 # b=B('egon') 62 # print(b.__dict__) 63 # 64 # b.__age=18 65 # print(b.__dict__) 66 # print(b.__age) 67 68 69 #驗證問題三: 70 # class A: 71 # def foo(self): 72 # print('A.foo') 73 # 74 # def bar(self): 75 # print('A.bar') 76 # self.foo() #b.foo() 77 # 78 # class B(A): 79 # def foo(self): 80 # print('B.foo') 81 # 82 # b=B() 83 # b.bar() 84 85 86 87 class A: 88 def __foo(self): #_A__foo 89 print('A.foo') 90 91 def bar(self): 92 print('A.bar') 93 self.__foo() #self._A__foo() 94 95 class B(A): 96 def __foo(self): #_B__foo 97 print('B.foo') 98 99 b=B() 100 b.bar()
封裝 1隱藏屬性
1 #一:封裝數據屬性:明確的區分內外,控制外部對隱藏的屬性的操作行為 2 # class People: 3 # def __init__(self,name,age): 4 # self.__name=name 5 # self.__age=age 6 # 7 # def tell_info(self): 8 # print('Name:<%s> Age:<%s>' %(self.__name,self.__age)) 9 # 10 # def set_info(self,name,age): 11 # if not isinstance(name,str): 12 # print('名字必須是字元串類型') 13 # return 14 # if not isinstance(age,int): 15 # print('年齡必須是數字類型') 16 # return 17 # self.__name=name 18 # self.__age=age 19 # 20 # p=People('egon',18) 21 # 22 # # p.tell_info() 23 # 24 # # p.set_info('EGON',38) 25 # # p.tell_info() 26 # 27 # # p.set_info(123,38) 28 # p.set_info('egon','38') 29 # p.tell_info() 30 31 32 #二、 封裝方法:隔離複雜度 33 34 class ATM: 35 def __card(self): 36 print('插卡') 37 def __auth(self): 38 print('用戶認證') 39 def __input(self): 40 print('輸入取款金額') 41 def __print_bill(self): 42 print('列印賬單') 43 def __take_money(self): 44 print('取款') 45 46 def withdraw(self): 47 self.__card() 48 self.__auth() 49 self.__input() 50 self.__print_bill() 51 self.__take_money() 52 53 a=ATM() 54 55 a.withdraw() 56 57 示例二: 58 class Room: 59 def __init__(self,name,owner,weight,length,height): 60 self.name=name 61 self.owner=owner 62 63 self.__weight=weight 64 self.__length=length 65 self.__height=height 66 67 def tell_area(self): 68 return self.__weight * self.__length * self.__height 69 70 r=Room('衛生間','alex',10,10,10) 71 72 # print(r.tell_area()) 73 74 print(r.tell_area())
封裝 示例
類的使用(二)
1 ''' 2 BMI指數(bmi是計算而來的,但很明顯它聽起來像是一個屬性而非方法,如果我們將其做成一個屬性,更便於理解) 3 4 成人的BMI數值: 5 6 過輕:低於18.5 7 8 正常:18.5-23.9 9 10 過重:24-27 11 12 肥胖:28-32 13 14 非常肥胖, 高於32 15 16 體質指數(BMI)=體重(kg)÷身高^2(m) 17 18 EX:70kg÷(1.75×1.75)=22.86 19 ''' 20 # class People: 21 # def __init__(self,name,weight,height): 22 # self.name=name 23 # self.weight=weight 24 # self.height=height 25 # 26 # @property 27 # def bmi(self): 28 # return self.weight / (self.height ** 2) 29 # 30 # p=People('egon',75,1.81) 31 # # p.bmi=p.weight / (p.height ** 2) 32 # # print(p.bmi) 33 # 34 # # print(p.bmi()) 35 # # print(p.bmi) 36 # 37 # # p.height=1.82 38 # # print(p.bmi) 39 # 40 # p.bmi=3333 #報錯AttributeError: can't set attribute 41 42 43 44 45 class People: 46 def __init__(self,name): 47 self.__name=name 48 49 @property 50 def name(self): 51 # print('getter') 52 return self.__name 53 54 @name.setter 55 def name(self,val): 56 # print('setter',val) 57 if not isinstance(val,str): 58 print('名字必須是字元串類型') 59 return 60 self.__name=val 61 62 @name.deleter 63 def name(self): 64 print('deleter') 65 66 print('不允許刪除') 67 68 69 p=People('egon') 70 71 # print(p.get_name()) 72 73 # print(p.name) 74 75 # p.name 76 # p.name='EGON' 77 # p.name=123 78 # print(p.name) 79 80 del p.name
property
1 ''' 2 在類內部定義的函數,分為兩大類: 3 一:綁定方法:綁定給誰,就應該由誰來調用,誰來調用就回把調用者當作第一個參數自動傳入 4 綁定到對象的方法:在類內定義的沒有被任何裝飾器修飾的 5 6 綁定到類的方法:在類內定義的被裝飾器classmethod修飾的方法 7 8 二:非綁定方法:沒有自動傳值這麼一說了,就類中定義的一個普通工具,對象和類都可以使用 9 非綁定方法:不與類或者對象綁定 10 11 12 13 ''' 14 15 class Foo: 16 def __init__(self,name): 17 self.name=name 18 19 def tell(self): 20 print('名字是%s' %self.name) 21 22 @classmethod 23 def func(cls): #cls=Foo 24 print(cls) 25 26 @staticmethod 27 def func1(x,y): 28 print(x+y) 29 30 f=Foo('egon') 31 32 # print(Foo.tell) 33 # Foo.tell(f) 34 # print(f.tell) 35 36 # f.tell() 37 38 # print(Foo.func) 39 # Foo.func() 40 41 # print(Foo.func1) 42 # print(f.func1) 43 44 Foo.func1(1,2) 45 f.func1(1,3) 46 47 48 49 應用 50 import settings 51 import hashlib 52 import time 53 54 class People: 55 def __init__(self,name,age,sex): 56 self.id=self.create_id() 57 self.name=name 58 self.age=age 59 self.sex=sex 60 61 def tell_info(self): #綁定到對象的方法 62 print('Name:%s Age:%s Sex:%s' %(self.name,self.age,self.sex)) 63 64 @classmethod 65 def from_conf(cls): 66 obj=cls( 67 settings.name, 68 settings.age, 69 settings.sex 70 ) 71 return obj 72 73 @staticmethod 74 def create_id(): 75 m=hashlib.md5(str(time.time()).encode('utf-8')) 76 return m.hexdigest() 77 78 # p=People('egon',18,'male') 79 80 #綁定給對象,就應該由對象來調用,自動將對象本身當作第一個參數傳入 81 # p.tell_info() #tell_info(p) 82 83 #綁定給類,就應該由類來調用,自動將類本身當作第一個參數傳入 84 # p=People.from_conf() #from_conf(People) 85 # p.tell_info() 86 87 88 #非綁定方法,不與類或者對象綁定,誰都可以調用,沒有自動傳值一說 89 p1=People('egon1',18,'male') 90 p2=People('egon2',28,'male') 91 p3=People('egon3',38,'male') 92 93 print(p1.id) 94 print(p2.id) 95 print(p3.id)
綁定方法
1 #反射:通過字元串映射到對象的屬性 2 # class People: 3 # country='China' 4 # 5 # def __init__(self,name,age): 6 # self.name=name 7 # self.age=age 8 # 9 # def talk(self): 10 # print('%s is talking' %self.name) 11 # 12 # 13 # obj=People('egon',18) 14 15 # print(obj.name) #obj.__dict__['name'] 16 # print(obj.talk) 17 18 19 # choice=input('>>: ') #choice='name' 20 # print(obj.choice) #print(obj.'name') 21 22 23 24 # print(hasattr(obj,'name')) #obj.name #obj.__dict__['name'] 25 # print(hasattr(obj,'talk')) #obj.talk 26 27 28 # print(getattr(obj,'namexxx',None)) 29 # print(getattr(obj,'talk',None)) 30 31 # setattr(obj,'sex','male') #obj.sex='male' 32 # print(obj.sex) 33 34 35 # delattr(obj,'age') #del obj.age 36 # print(obj.__dict__) 37 38 39 # print(getattr(People,'country')) #People.country 40 41 42 #反射的應用: 43 44 class Service: 45 def run(self): 46 while True: 47 inp=input('>>: ').strip() #cmd='get a.txt' 48 cmds=inp.split() #cmds=['get','a.txt'] 49 50 # print(cmds) 51 if hasattr(self,cmds[0]): 52 func=getattr(self,cmds[0]) 53 func(cmds) 54 55 56 def get(self,cmds): 57 print('get.......',cmds) 58 59 60 def put(self,cmds): 61 print('put.......',cmds) 62 63 64 65 obj=Service() 66 obj.run()
反射
1 #item系列 2 # class Foo: #Dict 3 # def __init__(self,name): 4 # self.name=name 5 # 6 # def __getitem__(self, item): #item='namexxx' 7 # # print('getitem...') 8 # return self.__dict__.get(item) 9 # 10 # def __setitem__(self, key, value): 11 # # print('setitem...') 12 # # print(key,value) 13 # self.__dict__[key]=value 14 # 15 # def __delitem__(self, key): 16 # # print('delitem...') 17 # # print(key) 18 # del self.__dict__[key] 19 # 20 # obj=Foo('egon') 21 # print(obj.__dict__) 22 23 24 #查看屬性: 25 # obj.屬性名 26 # print(obj['namexxx']) #obj.name 27 28 29 #設置屬性: 30 # obj.sex='male' 31 # obj['sex']='male' 32 33 # print(obj.__dict__) 34 # print(obj.sex) 35 36 37 #刪除屬性 38 # del obj.name 39 # del obj['name'] 40 # 41 # print(obj.__dict__) 42 43 44 45 46 47 #__str__方法: 48 # d=dict({'name':'egon'}) 49 # print(isinstance(d,dict)) 50 # print(d) 51 52 53 # class People: 54 # def __init__(self,name,age): 55 # self.name=name 56 # self.age=age 57 # 58 # def __str__(self): 59 # # print('====>str') 60 # return '<name:%s,age:%s>' %(self.name,self.age) 61 # 62 # obj=People('egon',18) 63 # print(obj) #res=obj.__str__() 64 65 66 #__del__ 67 68 # f=open('settings.py') 69 # f.read() 70 # f.close() #回收作業系統的資源 71 72 # print(f) 73 # f.read() 74 75 76 77 class Open: 78 def __init__(self,filename): 79 print('open file.......') 80 self.filename=filename 81 82 def __del__(self): 83 print('回收作業系統資源:self.close()') 84 85 f=Open('settings.py') 86 # del f #f.__del__() 87 print('----main------') #del f #f.__del__()
雙下劃線方法
1 #儲備知識exec 2 #參數1:字元串形式的命令 3 #參數2:全局作用域(字典形式),如果不指定默認就使用globals() 4 #參數3:局部作用域(字典形式),如果不指定默認就使用locals() 5 6 # g={ 7 # 'x':1, 8 # 'y':2 9 # } 10 # 11 # l={} 12 # 13 # exec(""" 14 # global x,m 15 # x=10 16 # m=100 17 # 18 # z=3 19 # """,g,l) 20 21 # print(g) 22 # print(l) 23 24 25 #一切皆對象,對象可以怎麼用? 26 #1、都可以被引用,x=obj 27 #2、都可以當作函數的參數傳入 28 #3、都可以當作函數的返回值 29 #4、都可以當作容器類的元素,l=[func,time,obj,1] 30 31 32 33 #類也是對象,Foo=type(....) 34 # class Foo: 35 # pass 36 # 37 # obj=Foo() 38 # print(type(obj)) 39 # print(type(Foo)) 40 # 41 # 42 # class Bar: 43 # pass 44 # 45 # print(type(Bar)) 46 47 #產生類的類稱之為元類,默認所以用class定義的類,他們的元類是type 48 49 #定義類的兩種方式: 50 #方式一:class 51 class Chinese: #Chinese=type(...) 52 country='China' 53 54 def __init__(self,namem,age): 55 self.name=namem 56 self.age=age 57 58 def talk(self): 59 print('%s is talking' %self.name) 60 61 # print(Chinese) 62 obj=Chinese('egon',18) 63 print(obj,obj.name,obj.age) 64 #方式二:type 65 66 #定義類的三要素:類名,類的基類們,類的名稱空間 67 class_name='Chinese' 68 class_bases=(object,) 69 70 class_body=""" 71 country='China' 72 73 def __init__(self,namem,age): 74 self.name=namem 75 self.age=age 76 77 def talk(self): 78 print('%s is talking' %self.name) 79 """ 80 81 class_dic={} 82 exec(class_body,globals(),class_dic) 83 # print(class_dic) 84 85 Chinese1=type(class_name,class_bases,class_dic) 86 # print(Chinese1) 87 88 obj1=Chinese1('egon',18) 89 print(obj1,obj1.name,obj1.age)
元類介紹
1 class Mymeta(type): 2 def __init__(self,class_name,class_bases,class_dic): 3 if not class_name.istitle(): 4 raise TypeError('類名的首字母必須大寫') 5 6 if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): 7 raise TypeError('必須有注釋,且注釋不能為空') 8 9 super(Mymeta,self).__init__(class_name,class_bases,class_dic) 10 11 class Chinese(object,metaclass=Mymeta): 12 ''' 13 中文人的類 14 ''' 15 country='China' 16 17 def __init__(self,namem,age): 18 self.name=namem 19 self.age=age 20 21 def talk(self): 22 print('%s is talking' %self.name) 23 24 25 # Chinese=Mymeta(class_name,class_bases,class_dic)
自定義元類控制類的行為
1 #知識儲備__call__方法 2 # class Foo: 3 # def __call__(self, *args, **kwargs): 4 # print(self) 5 # print(args) 6 # print(kwargs) 7 # 8 # 9 # obj=Foo() 10 # 11 # obj(1,2,3,a=1,b=2,c=3) #obj.__call__(obj,1,2,3,a=1,b=2,c=3) 12 # 13 # 14 # #元類內部也應有有一個__call__方法,會在調用Foo時觸發執行 15 # #Foo(1,2,x=1) #Foo.__call__(Foo,1,2,x=1) 16 17 18 19 20 class Mymeta(type): 21 def __init__(self,class_name,class_bases,class_dic): 22 if not class_name.istitle(): 23 raise TypeError('類名的首字母必須大寫') 24 25 if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): 26 raise TypeError('必須有注釋,且注釋不能為空') 27 28 super(Mymeta,self).__init__(class_name,class_bases,class_dic) 29 30 def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) 31 # print(self) #self=Chinese 32 # print(args) #args=('egon',) 33 # print(kwargs) #kwargs={'age': 18} 34 35 #第一件事:先造一個空對象obj 36 obj=object.__new__(self) 37 #第二件事:初始化obj 38 self.__init__(obj,*args,**kwargs) 39 #第三件事:返回obj 40 return obj 41 42 class Chinese(object,metaclass=Mymeta): 43 ''' 44 中文人的類 45 ''' 46 country='China' 47 48 def __init__(self,namem,age): 49 self.name=namem 50 self.age=age 51 52 def talk(self): 53 print('%s is talking' %self.name) 54 55 56 57 58 obj=Chinese('egon',age=18) #Chinese.__call__(Chinese,'egon',18) 59 60 print(obj.__dict__)
自定義元類控制類的實例化行為
1 #單例模式 2 #實現方式一: 3 # class MySQL: 4 # __instance=None #__instance=obj1 5 # 6 # def __init__(self): 7 # self.host='127.0.0.1' 8 # self.port=3306 9 # 10 # @classmethod 11 # def singleton(cls): 12 # if not cls.__instance: 13 # obj=cls() 14 # cls.__instance=obj 15 # return cls.__instance 16 # 17 # 18 # def conn(self): 19 # pass 20 # 21 # def execute(self): 22 # pass 23 # 24 # 25 # # obj1=MySQL() 26 # # obj2=MySQL() 27 # # obj3=MySQL() 28 # # 29 # # print(obj1) 30 # # print(obj2) 31 # # print(obj3) 32 # 33 # obj1=MySQL.singleton() 34 # obj2=MySQL.singleton() 35 # obj3=MySQL.singleton() 36 # 37 # print(obj1 is obj3) 38 39 40 41 42 #實現方式二:元類的方式 43 class Mymeta(type): 44 def __init__(self,class_name,class_bases,class_dic): 45 if not class_name.istitle(): 46 raise TypeError('類名的首字母必須大寫') 47 48 if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): 49 raise TypeError('必須有注釋,且注釋不能為空') 50 51 super(Mymeta,self).__init__(class_name,class_bases,class_dic) 52 self.__instance=None 53 54 def __call__(self, *args, **kwargs): #obj=Chinese('egon',age=18) 55 if not self.__instance: 56 obj=object.__new__(self) 57 self.__init__(obj) 58 self.__instance=obj 59 60 return self.__instance 61 62 63 64 class Mysql(object,metaclass=Mymeta): 65 ''' 66 mysql xxx 67 ''' 68 def __init__(self): 69 self.host='127.0.0.1' 70 self.port=3306 71 72 def conn(self): 73 pass 74 75 def execute(self): 76 pass 77 78 79 80 obj1=Mysql() 81 obj2=Mysql() 82 obj3=Mysql() 83 84 print(obj1 is obj2 is obj3)
應用
- 異常處理
1 #1 什麼是異常:異常是錯誤發生的訊號,一旦程式出錯,並且程式沒有處理這個錯誤,那個就會拋出異常,並且程式的運行隨之終止 2 # 3 # print('1') 4 # print('2') 5 # print('3') 6 # int('aaaa') 7 # print('4') 8 # print('5') 9 # print('6') 10 11 #2 錯誤分為兩種: 12 #語法錯誤:在程式執行前就要立刻改正過來 13 # print('xxxx' 14 # if 1 > 2 15 16 #邏輯錯誤 17 18 #ValueError 19 # int('aaa') 20 21 #NameError 22 # name 23 24 #IndexError 25 # l=[1,2,3] 26 # l[1000] 27 28 #KeyError 29 # d={} 30 # d['name'] 31 32 33 #AttributeError 34 # class Foo: 35 # pass 36 # 37 # Foo.xxx 38 39 40 #ZeroDivisionError: 41 # 1/0 42 43 44 #TypeError:int類型不可迭代 45 # for i in 3: 46 # pass 47 48 # import time 49 # time.sleep(1000) 50 51 52 53 #3 異常 54 #強調一:錯誤發生的條件如果是可以預知的,此時應該用if判斷去預防異常 55 # AGE=10 56 # age=input('>>: ').strip() 57 # 58 # if age.isdigit(): 59 # age=int(age) 60 # if age > AGE: 61 # print('太大了') 62 63 64 #強調二:錯誤發生的條件如果是不可預知的,此時應該用異常處理機制,try...except 65 try: 66 f=open('a.txt','r',encoding='utf-8') 67 68 print(next(f),end='') 69 print(next(f),end='') 70 print(next(f),end='') 71 print(next(f),end='') 72 73 print(next(f),end='') 74 print(next(f),end='') 75 print(next(f),end='') 76 77 f.close() 78 except StopIteration: 79 print('出錯啦') 80 81 82 print('====>1') 83 print('====>2') 84 print('====>3')
異常處理
1 #多分支:被監測的程式碼塊拋出的異常有多種可能性,並且我們需要針對每一種異常類型都訂製專門的處理邏輯 2 # try: 3 # print('===>1') 4 # # name 5 # print('===>2') 6 # l=[1,2,3] 7 # # l[100] 8 # print('===>3') 9 # d={} 10 # d['name'] 11 # print('===>4') 12 # 13 # except NameError as e: 14 # print('--->',e) 15 # 16 # except IndexError as e: 17 # print('--->',e) 18 # 19 # except KeyError as e: 20 # print('--->',e) 21 # 22 # 23 # print('====>afer code') 24 25 26 #萬能異常:Exception,被監測的程式碼塊拋出的異常有多種可能性, 27 # 並且我們針對所有的異常類型都只用一種處理邏輯就可以了,那就使用Exception 28 # try: 29 # print('===>1') 30 # # name 31 # print('===>2') 32 # l=[1,2,3] 33 # l[100] 34 # print('===>3') 35 # d={} 36 # d['name'] 37 # print('===>4') 38 # 39 # except Exception as e: 40 # print('異常發生啦:',e) 41 # 42 # print('====>afer code') 43 44 45 46 47 # try: 48 # print('===>1') 49 # # name 50 # print('===>2') 51 # l=[1,2,3] 52 # # l[100] 53 # print('===>3') 54 # d={} 55 # d['name'] 56 # print('===>4') 57 # 58 # except NameError as e: 59 # print('--->',e) 60 # 61 # except IndexError as e: 62 # print('--->',e) 63 # 64 # except KeyError as e: 65 # print('--->',e) 66 # 67 # except Exception as e: 68 # print('統一的處理方法') 69 # 70 # 71 # print('====>afer code') 72 73 #其他結構 74 # try: 75 # print('===>1') 76 # # name 77 # print('===>2') 78 # l=[1,2,3] 79 # # l[100] 80 # print('===>3') 81 # d={} 82 # d['name'] 83 # print('===>4') 84 # 85 # except NameError as e: 86 # print('--->',e) 87 # 88 # except IndexError as e: 89 # print('--->',e) 90 # 91 # except KeyError as e: 92 # print('--->',e) 93 # 94 # except Exception as e: 95 # print('統一的處理方法') 96 # 97 # else: 98 # print('在被檢測的程式碼塊沒有發生異常時執行') 99 # 100 # finally: 101 # print('不管被檢測的程式碼塊有無發生異常都會執行') 102 # 103 # 104 # 105 # print('====>afer code') 106 107 108 # try: 109 # f=open('a.txt','r',encoding='utf-8') 110 # print(next(f)) 111 # print(next(f)) 112 # print(next(f)) 113 # print(next(f)) 114 # 115 # print(next(f)) 116 # print(next(f)) 117 # finally: 118 # f.close() 119 120 121 #主動觸發異常:raise 異常類型(值) 122 # class People: 123 # def __init__(self,name,age): 124 # if not isinstance(name,str): 125 # raise TypeError('名字必須傳入str類型') 126 # if not isinstance(age,int): 127 # raise TypeError('年齡必須傳入int類型') 128 # 129 # self.name=name 130 # self.age=age 131 # 132 # p=People('egon',18) 133 134 135 #自定義異常類型 136 class MyException(BaseException): 137 def __init__(self,msg): 138 super(MyException,self).__init__() 139 self.msg=msg 140 141 def __str__(self): 142 return '<%s>' %self.msg 143 144 raise MyException('我自己的異常類型') #print(obj) 145 146 147 148 149 150 151 #斷言assert 152 153 # info={} 154 # info['name']='egon' 155 # # info['age']=18 156 # 157 # 158 # 159 # 160 # 161 # 162 # # if 'name' not in info: 163 # # raise KeyError('必須有name這個key') 164 # # 165 # # if 'age' not in info: 166 # # raise KeyError('必須有age這個key') 167 # 168 # assert ('name' in info) and ('age' in info) 169 # 170 # 171 # 172 # if info['name'] == 'egon' and info['age'] > 10: 173 # print('welcome') 174 175 176 177 178 try: 179 pass 180 181 182 except Exception: 183 pass
try..except 的詳細用法