核心是過程二字,過程是指解決問題的步驟,即設計一條流水線,先作什麼,後作什麼,再作什麼,是一種機械式的思惟方式;html
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 5:21
#需求,寫一個網站用戶註冊功能;使用面向過程的編程範式;
import json,re def interactive(): name = input('>>:').strip() passwd = input('>>:').strip() #拓展需求; email = input('>>:').strip() return { 'name':name, 'passwd':passwd, 'email':email, } def check(user_info): is_valid = True if len(user_info['name']) == 0: print('用戶名不能爲空。') is_valid = False if len(user_info['passwd']) < 6: print('密碼不能少於6位。') is_valid = False # 拓展需求; if not re.search(r'@.*?\.com$',user_info['email']): print('郵箱格式不合法。') is_valid = False return { 'is_valid':is_valid, 'user_info':user_info, } def register(check_info): if check_info['is_valid']: with open(file='db.json',mode='w',encoding='utf-8') as f: json.dump(check_info['user_info'],f) #定義主函數main() def main(): user_info = interactive() check_info = check(user_info) register(check_info) if __name__ == '__main__': main()
強調:站在不一樣的角度,獲得的分類是不同的,好比站在實體的角度,人和鉛筆、計算機是一類;站在生物的角度,以上就不是相同的一類;java
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 5:47 "" """ 一、將對象進行分類,好比PC、筆記本; """ #使用clasee關鍵字,先定義類; class LuffyStudent:#類名首字母大寫; school = 'luffycity' def learn(self):#技能就是功能,經過函數方式進行定義! print('is learning.') def eat(self): print('is eating.') def sleep(self): print('is sleeping.') #後產生對象; student1 = LuffyStudent()#類產生對象的這個過程也稱爲實例化的過程;類名加()有別於函數名加括號; student2 = LuffyStudent() student3 = LuffyStudent() print(student1)#<__main__.LuffyStudent object at 0x000001E494370B00>#對象在類中的內存地址; print(student2)#<__main__.LuffyStudent object at 0x000001E494370B38> print(student3)#<__main__.LuffyStudent object at 0x000001E494370AC8>
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 6:05 #先定義類; class LuffyStudent:#類名首字母大寫; school = 'luffycity'#特徵,以變量的形式定義; def learn(self):#技能1,以函數的形式定義; print('is learning.') def eat(self):#技能2,以函數的形式定義; print('is eating.') def sleep(self):#技能3,以函數的形式定義; print('is sleeping.') #查看類的名稱空間; print(LuffyStudent.__dict__)#{'__module__': '__main__', 'school': 'luffycity', 'learn': <function LuffyStudent.learn at 0x000001A59EE71AE8>, 'eat': <function LuffyStudent.eat at 0x000001A59EE71EA0>, 'sleep': <function LuffyStudent.sleep at 0x000001A59EE71B70>, '__dict__': <attribute '__dict__' of 'LuffyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'LuffyStudent' objects>, '__doc__': None} print(LuffyStudent.__dict__['school'])#luffycity print(LuffyStudent.__dict__['learn'])#<function LuffyStudent.learn at 0x0000021C5B221AE8> """ 類內部定義的變量稱之爲:數據屬性; 類內部定義的函數稱之爲:函數屬性; """ #import time #time.sleep(1) #查看; print(LuffyStudent.school)#luffycity print(LuffyStudent.learn)#<function LuffyStudent.learn at 0x000002A0CD0B1AE8> #增長; LuffyStudent.country = 'China'#定義新的數據屬性(即公共的特性,變量名),進行賦值; #print(LuffyStudent.__dict__) #使用專門的語法進行; print(LuffyStudent.country)#China #刪除; del LuffyStudent.country print(LuffyStudent.__dict__)#發現country已經被刪除; #print(LuffyStudent.country)#AttributeError: type object 'LuffyStudent' has no attribute 'country' #改; LuffyStudent.school = 'Luffycity'#即從新賦值; print(LuffyStudent.school)#Luffycity """ 小結: 一、函數名加(),執行函數; 二、類名加(),實例化獲得一個對象; 三、類的用途:對類屬性的操做——增刪改查;實例化產生出對象;
四、類與函數的區別,類在定義階段,就已經被執行;
五、類的兩大操做,第一,類的增刪改查;第二,類的實例化產生對象; """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 6:41 #__init__方法,用來爲對象定製對象本身獨有的特徵;好比崔曉昭、崔曉珊、崔曉思、崔曉磊都屬於崔家類,但都有各自的屬性;好比職業、年齡、身高、體重、價值觀等等; #先定義類; class LuffyStudent:#類名首字母大寫; school = 'luffycity' #student1,'王二丫','女',18 def __init__(self,name,sex,age): self.name = name self.sex = sex self.age = age #student1.Name='王二丫' #student2.Sex='女' #student3.Age=18 def learn(self): print('is learning.') def eat(self): print('is eating.') def sleep(self): print('is sleeping.') #後產生對象; #student1 = LuffyStudent()#TypeError: __init__() missing 3 required positional arguments: 'name', 'sex', and 'age' #進行類的實例化的時候,Python會自動調用__init__對象; student1 = LuffyStudent('王二丫','女',18) #加上__init__方法後,實例化的步驟; """ 一、先產生一個空對象student1; 二、LuffyStudent.__init__(student1,'王二丫','女',18) """ #查詢; print(student1.__dict__)#{'Name': '王二丫', 'Sex': '女', 'Age': 18} print(student1.name)#王二丫 print(student1.age)#18 print(student1.sex)#女 #改-即對對象的從新賦值操做; student1.Name = '李靜瓶' print(student1.__dict__)#{'Name': '李靜瓶', 'Sex': '女', 'Age': 18} print(student1.Name)#李靜瓶 #刪除 del student1.Name#使用del 方法; print(student1.__dict__) #增長 student1.Course = 'Python全棧開發'#{'name': '王二丫', 'sex': '女', 'age': 18, 'Course': 'Python全棧開發'} print(student1.__dict__) #如何產生對象2:student2操做 student2 = LuffyStudent('李三炮','男',38) print(student2.__dict__)#{'Name': '李三炮', 'Sex': '男', 'Age': 38} print(student2.name)#李三炮 print(student2.age)#38 print(student2.sex)#男 #問題1:在對象中,可否訪問到類裏面的公共屬性呢?!
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 7:04 #先定義類; class LuffyStudent:#類名首字母大寫; school = 'luffycity' #student1,'王二丫','女',18 def __init__(self,name,sex,age): self.Name = name self.Sex = sex self.Age = age #student1.Name='王二丫' #student2.Sex='女' #student3.Age=18 def learn(self): #print('is learning.') print('%s is learning'%self.Name) def eat(self): print('is eating.') def sleep(self): print('is sleeping.') #後產生對象; #student1 = LuffyStudent()#TypeError: __init__() missing 3 required positional arguments: 'name', 'sex', and 'age' #Python會自動調用__init對象; student1 = LuffyStudent('王二丫','女',18) student2 = LuffyStudent('李三炮','男',38) student3 = LuffyStudent('張鐵蛋','男',48) print(student1.__dict__) print(student2.__dict__) print(student3.__dict__) "" {'Name': '王二丫', 'Sex': '女', 'Age': 18} {'Name': '李三炮', 'Sex': '男', 'Age': 38} {'Name': '張鐵蛋', 'Sex': '男', 'Age': 48} "" #對象:特徵與技能的結合體,好比孫悟空這個角色; #類:類是一系列對象類似的特徵與類似的技能的結合體; #類中的數據屬性:是全部的對象公共的即共有的; print(LuffyStudent.school) print(student1.school,id(student1.school)) print(student2.school,id(student2.school)) print(student3.school,id(student3.school)) """ luffycity luffycity 2904853177648 luffycity 2904853177648 luffycity 2904853177648 """ #類中的函數屬性:是綁定給對象使用的,綁定到不一樣的對象是不一樣的綁定方法; #對象調用綁定方法時候,會把對象自己,當作第一個函數傳入,傳給self; print(LuffyStudent.learn) print(student1.learn) print(student2.learn) print(student3.learn) """ <function LuffyStudent.learn at 0x00000234A0FC1B70>#函數; <bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5C88>>#bound method綁定方法; <bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5CC0>> <bound method LuffyStudent.learn of <__main__.LuffyStudent object at 0x00000234A0FC5CF8>> """ #LuffyStudent.learn()#TypeError: learn() missing 1 required positional argument: 'self' LuffyStudent.learn(student1)#王二丫 is learning student1.learn()#王二丫 is learning """ 小結: 一、類中定義的函數是給對象使用的,綁定給對象使用,不一樣的對象具有相同的技能,但內存地址不一致; """ student1.x = 'from student1'#給對象增長一個屬性; LuffyStudent.x = 'from LuffyCity class ' print(student1.__dict__)#{'Name': '王二丫', 'Sex': '女', 'Age': 18, 'x': 'from student1'} print(student1.x)#from student1
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 7:30 "" """ 小結: 一、站的角度不一樣,定義出的類是大相徑庭的; 二、現實生活中的類不徹底等於程序中的類,好比現實中的公司類,在程序中有時須要拆分紅部門類、業務類等; 三、有時候爲了編程需求,程序中也有可能會定義現實中不存在的類,好比策略類,現實中並不存在,可是在程序中倒是一個很常見的類; 補充: 一、Python當中一切皆對象,Python3.x中統一了類與數據類型的概念; """ #先定義類; class LuffyStudent:#類名首字母大寫; school = 'luffycity' #student1,'王二丫','女',18 def __init__(self,name,sex,age): self.Name = name self.Sex = sex self.Age = age #student1.Name='王二丫' #student2.Sex='女' #student3.Age=18 def learn(self): #print('is learning.') print('%s is learning'%self.Name) def eat(self): print('is eating.') def sleep(self): print('is sleeping.') print(LuffyStudent) print(list) """ <class '__main__.LuffyStudent'> <class 'list'> """ l1 = [1,2,3]#等價於,l1 = list([1,2,3]) l2 =[]#等價於,l2 = list([]) #列表的內置方法; l1.append(4) print(l1)#[1, 2, 3, 4] print(l2)#[] list.append(l1,4)#雖然能夠實現功能,可是沒人這麼用,咱們都是使用對象的綁定方法;好比l1.append() print(l1)#[1, 2, 3, 4, 4],效果等價於l1.append(4)
#總結:針對於對象,咱們使用的都是對象的綁定方法來操做;能夠簡單理解,類就是咱們自定義的list、tuple、set等數據類型;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 7:40 "" class Chinese: country = 'China' def __init__(self,name,sex,age): self.Name = name self.Sex = sex self.Age = age #student1.Name='王二丫' #student2.Sex='女' #student3.Age=18 def learn(self): #print('is learning.') print('%s is learning'%self.Name) def eat(self): print('%s is eating.'%self.Name) p1 = Chinese('egon',18,'male') p2 = Chinese('alex',38,'female') p3 = Chinese('wqp',48,'female') print(p1.country)#china print(p2.country)#china print(p3.country)#china p1.eat() p2.eat() p3.eat() """ egon is eating. alex is eating. wqp is eating. """
從代碼級別看面向對象 1、在沒有學習類這個概念時,數據與功能是分離的; def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx def exc2(host,port,db,charset,proc_name)#proc_name是MySQL中的存儲過程; conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx #每次調用都須要重複傳入一堆參數; exc1('127.0.0.1',3306,'db1','utf8','select * from tb1;') exc2('127.0.0.1',3306,'db1','utf8','存儲過程的名字') 2、咱們能想到的解決方法是,把這些變量都定義成全局變量; HOST=‘127.0.0.1’#大寫字母表明常量; PORT=3306 DB=‘db1’ CHARSET=‘utf8’ def exc1(host,port,db,charset): conn=connect(host,port,db,charset) conn.execute(sql) return xxx def exc2(host,port,db,charset,proc_name) conn=connect(host,port,db,charset) conn.call_proc(sql) return xxx exc1(HOST,PORT,DB,CHARSET,'select * from tb1;') exc2(HOST,PORT,DB,CHARSET,'存儲過程的名字') 3、可是2的解決方法也是有問題的,按照2的思路,咱們將會定義一大堆全局變量,這些全局變量並無作任何區分,即可以被全部功能使用,然而事實上只有HOST,PORT,DB,CHARSET是給exc1和exc2這兩個功能用的。言外之意:咱們必須找出一種可以將數據與操做數據的方法組合到一塊兒的解決方法,這就是咱們說的類了 class MySQLHandler:#注意此處沒有(); def __init__(self,host,port,db,charset='utf8'): self.host=host self.port=port self.db=db self.charset=charset self.conn=connect(self.host,self.port,self.db,self.charset) def exc1(self,sql): return self.conn.execute(sql) def exc2(self,sql): return self.conn.call_proc(sql) obj=MySQLHandler('127.0.0.1',3306,'db1') obj.exc1('select * from tb1;') obj.exc2('存儲過程的名字') 總結使用類能夠: 一、將數據與專門操做該數據的功能整合到一塊兒; 二、可擴展性高; 三、定義類併產生三個對象; class Chinese: def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex p1=Chinese('egon',18,'male') p2=Chinese('alex',38,'female') p3=Chinese('wpq',48,'female') 若是咱們新增一個類屬性,將會馬上反映給全部對象,而對象卻無需修改; class Chinese: country='China' def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def tell_info(self): info=''' 國籍:%s 姓名:%s 年齡:%s 性別:%s ''' %(self.country,self.name,self.age,self.sex) print(info)
p1=Chinese('egon',18,'male') p2=Chinese('alex',38,'female') p3=Chinese('wpq',48,'female') print(p1.country) p1.tell_info()
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 21:03 "" """ 一、練習1:編寫一個學生類,產生一堆學生對象; 要求: 有一個計算器(屬性),統計總共實例化了多少個對象。count方法統計; """ class Student:#定義一個Student類名,注意首字母大寫; school = 'luffycity' count = 0#在類中定義計數器變量count def __init__(self,name,age,sex):#約定俗稱,你們都寫self,能夠寫成其餘的,可是沒人這麼幹! self.name = name self.age = age self.sex = sex #self.Come = come Student.count +=1#經過類名的count方法統計調用次數,每調用一次,自增1; #self.count = self.count+1 def learn(self): print('%s is learning'%self.name) #實例化; stu1=Student('alex','male',38) stu2=Student('jinxing','female',78) stu3=Student('egon','male',18) print(Student.count) print(stu1.count) print(stu2.count) print(stu3.count) print(stu1.__dict__) print(stu2.__dict__) print(stu3.__dict__) """ 3 3 3 3 {'Name': 'alex', 'Age': 'male', 'Sex': 38} {'Name': 'jinxing', 'Age': 'female', 'Sex': 78} {'Name': 'egon', 'Age': 'male', 'Sex': 18} """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 21:20 "" """ 一、練習2:模仿LOL定義兩個英雄類; 要求: 一、英雄須要有暱稱、攻擊力、生命值等屬性; 二、實例化出兩個英雄對象; 三、英雄之間能夠互毆,被毆打的一方開始掉血,血量小於0則斷定爲死亡; """ #定義LOL中英雄的名稱; class Garen: camp = 'Demacia'#德瑪西亞; def __init__(self,nickname,life_value,aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attact(self,enemy): enemy.life_value -= self.aggresivity class Riven: camp = 'Noxus'#xxxx; def __init__(self,nickname,life_value,aggresivity): self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attact(self,enemy): enemy.life_value -= self.aggresivity g1=Garen('草叢倫',100,30) r1 = Riven('可愛的芮雯雯',80,50) #打印初始生命值; print(r1.life_value)#80 g1.attact(r1) #打印被攻擊一次後的生命值; print(r1.life_value)#50
class ParentClass1: #定義父類; pass class ParentClass2: #定義父類; pass class SubClass1(ParentClass1): #單繼承,基類是ParentClass1,派生類是SubClass; pass class SubClass2(ParentClass1,ParentClass2): #python支持多繼承,用逗號分隔開多個繼承的類; pass
>>> SubClass1.__bases__ #__base__只查看從左到右繼承的第一個子類,__bases__則是查看全部繼承的父類; (<class '__main__.ParentClass1'>,) >>> SubClass2.__bases__ (<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>)
1.只有在python2中才分新式類和經典類,python3中統一都是新式類; 2.在python2中,沒有顯式的繼承object類的類,以及該類的子類,都是經典類; 3.在python2中,顯式地聲明繼承object的類,以及該類的子類,都是新式類; 4.在python3中,不管是否繼承object,都默認繼承object,即python3中全部類均爲新式類;
# #!/usr/bin/env python # # -*- coding:utf-8 -*- # # __Author__:Administrator # # Version:python3.6.5 # # Date:2018/6/12 0012 21:38 # #定義一個父類1; # class ParentClass1: # pass # #定義一個父類2; # class ParentClass2: # pass # #定義一個子類1; # class SubClass1(ParentClass1): # pass # #定義一個子類2;同時繼承兩個父類; # class SubClass2(ParentClass1,ParentClass2): # pass
#__bases__方法,查看繼承了哪一個父類;
# print(SubClass1.__bases__)#(<class '__main__.ParentClass1'>,) # print(SubClass2.__bases__)#(<class '__main__.ParentClass1'>, <class '__main__.ParentClass2'>) #解決代碼之間冗餘問題; class Hero:#定義一個英雄類; x = 3 def __init__(self,nickname,life_value,aggresivity):#屬性; self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attact(self,enemy):#攻擊技能; enemy.life_value -= self.aggresivity class Garen(Hero): #x = 2 pass#德瑪西亞; class Riven(Hero): pass g1=Garen('剛們',29,30) print(g1.nickname,g1.life_value,g1.aggresivity)#剛們 29 30; #繼承,實現代碼的重用性! #那麼問題來了,屬性的查找順序是怎樣的? #g1.x =1 print(g1.x) #屬性查找的小練習; class Foo: def f1(self): print('from Foo.f1') def f2(self): print('from Foo.f2') self.f1()#b.f1(),注意查找順序,從下往上查找; class Bar(Foo): def f1(self): print('from Bar.f1') b = Bar() print(b.__dict__) b.f2() b.f1()#注意查找順序; """
from Foo.f2
from Bar.f1 from Bar.f1 """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 22:17 #派生的概念引入; class Hero:#定義一個英雄類; def __init__(self,nickname,life_value,aggresivity):#屬性; self.nickname = nickname self.life_value = life_value self.aggresivity = aggresivity def attact(self,enemy):#攻擊技能; enemy.life_value -= self.aggresivity class Garen(Hero): camp ='Demacia'#德瑪西亞; class Riven(Hero): camp = 'Noxus' g = Garen('草叢倫',100,30) r = Riven('銳雯雯',80,50) print(g.camp)#Demacia g.attact(r) print(r.life_value)#50
python究竟是如何實現繼承的,對於咱們定義的每個類,python會計算出一個方法解析順序(MRO)列表,這個MRO列表就是一個簡單的全部基類的線性順序列表,例如;python
>>> F.mro() #等同於F.__mro__ [<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
爲了實現繼承,python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類爲止。而這個MRO列表的構造是經過一個C3線性化算法來實現的。咱們不去深究這個算法的數學原理,它實際上就是合併全部父類的MRO列表並遵循以下三條準則:linux
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/12 0012 22:27 "" """
Python分爲兩種類;
一、新式類; 二、經典類; 在Python2中,沒有繼承object的類以及它的子類都稱之爲經典類;
在Python2中,繼承了object的類以及它的子類都稱之爲新式類; """ # class Foo: # pass # class Bar(Foo): # pass # #在Python3中統一爲新式類,一個類沒有繼承object類,默認就繼承object; # class Foo(): # pass # print(Foo.__bases__) #驗證多繼承狀況下的屬性查找順序; class A(object):#Python2中經典類去掉object # def test(self): # print('from A') pass#AttributeError: 'F' object has no attribute 'test' class B(A): # def test(self): # print('from B') pass class C(A): # def test(self): # print('from C') pass class D(B): # def test(self): # print('from D') pass class E(C): # def test(self): # print('from E') pass class F(D,E): # def test(self): # print('from F') pass #FDBECA # f=F() # f.test() print(F.mro())#[<class '__main__.F'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.E'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]
print(F.__mro__) #只有新式纔有這個屬性能夠查看線性列表,經典類沒有這個屬性; #新式類繼承順序:F->D->B->E->C->A; #經典類繼承順序:F->D->B->A->E->C; #python3中統一都是新式類; #pyhon2中才分新式類與經典類;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/13 0013 23:22 # class Hero:#定義一個英雄類; # def __init__(self,nickname,life_value,aggresivity):#屬性; # self.nickname = nickname # self.life_value = life_value # self.aggresivity = aggresivity # def attact(self,enemy):#攻擊技能; # enemy.life_value -= self.aggresivity # class Garen(Hero): # camp ='Demacia'#德瑪西亞; # def attack(self,enemy): # Hero.attact(self.enemy)#在子類當中,重用父類的方法,即指名道姓的重用父類的方法; # print('from Garen Class') # # class Riven(Hero): # camp = 'Noxus' # # g = Garen('草叢倫',100,30) # r = Riven('銳雯雯',80,50) # # print(r.life_value)#80 # g.attact(r)#進行攻擊; # print(r.life_value)#50; # class Hero:#定義一個英雄類; # def __init__(self,nickname,life_value,aggresivity):#屬性; # self.nickname = nickname # self.life_value = life_value # self.aggresivity = aggresivity # def attact(self,enemy):#攻擊技能; # enemy.life_value -= self.aggresivity # class Garen(Hero): # camp ='Demacia'#德瑪西亞; # def __init__(self,nickname,life_value,aggresivity,weapon): # #self.nickname = nickname # #self.life_value = life_value # #self.aggresivity = aggresivity # self.weapon = weapon # Hero.__init__(self,nickname,life_value,aggresivity)#實現了代碼節省的方法; # def attack(self,enemy): # Hero.attact(self.enemy)#指名道姓; # print('from Garen Class') # # # # #g = Garen('草叢倫',100,30)#TypeError: __init__() missing 1 required positional argument: 'weapon' # g = Garen('草叢倫',100,30,'金箍棒') # print(g.__dict__)#{'nickname': '草叢倫', 'life_value': 100, 'aggresivity': 30, 'weapon': '金箍棒'} "" """ 一、在子類派生出的新的方法中重用父類的方法,有兩種實現方式; 方式一:指名道姓(不依賴繼承); 方式二:super()方法(依賴繼承); """ #方式二:super()方法; # class Hero:#定義一個英雄類; # def __init__(self,nickname,life_value,aggresivity):#屬性; # self.nickname = nickname # self.life_value = life_value # self.aggresivity = aggresivity # def attack(self,enemy):#攻擊技能; # enemy.life_value -= self.aggresivity # # class Garen(Hero): # camp = 'Demacia'#德瑪西亞; # def attack(self,enemy): # super(Garen,self).attack(enemy)#依賴繼承的方式,進行重用父類的方法; # print('from Garen Class') # # class Riven(Hero): # camp = 'Noxus' # # g = Garen('草叢倫',100,30) # r = Riven('銳雯雯',80,50) # g.attack(r) # print(r.life_value) # class Hero:#定義一個英雄類; # def __init__(self,nickname,life_value,aggresivity):#屬性; # self.nickname = nickname # self.life_value = life_value # self.aggresivity = aggresivity # def attact(self,enemy):#攻擊技能; # enemy.life_value -= self.aggresivity # class Garen(Hero): # camp ='Demacia'#德瑪西亞; # def attack(self,enemy): # Hero.attact(self.enemy)#指名道姓; # print('from Garen Class') # # class Riven(Hero): # camp = 'Noxus' # # g = Garen('草叢倫',100,30) # r = Riven('銳雯雯',80,50) # # print(r.life_value)#80 # g.attact(r) # print(r.life_value)#50 # class Hero:#定義一個英雄類; # def __init__(self,nickname,life_value,aggresivity):#屬性; # self.nickname = nickname # self.life_value = life_value # self.aggresivity = aggresivity # def attack(self,enemy):#攻擊技能; # enemy.life_value -= self.aggresivity # class Garen(Hero): # camp ='Demacia'#德瑪西亞; # def __init__(self,nickname,life_value,aggresivity,weapon): # #self.nickname = nickname # #self.life_value = life_value # #self.aggresivity = aggresivity # #self.weapon = weapon # #Hero.__init__(self,nickname,life_value,aggresivity)# # #super(Garen,self).__init__(nickname,life_value,aggresivity)#與下方實現效果等價; # super().__init__(nickname,life_value,aggresivity)#Python3中super方法的簡寫方式; # self.weapon = weapon # def attack(self,enemy): # Hero.attack(self,enemy)#指名道姓; # print('from Garen Class') # # #g = Garen('草叢倫',100,30)#TypeError: __init__() missing 1 required positional argument: 'weapon' # g = Garen('草叢倫',100,30,'金箍棒') # print(g.__dict__)#{'nickname': '草叢倫', 'life_value': 100, 'aggresivity': 30, 'weapon': '金箍棒'}
#證實以下: class A: def f1(self): print('from A') class B: def f2(self): print('from B') class C(A,B): pass print(C.mro())#[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>]#c的mro排列順序查找;
1)繼承的方式程序員
經過繼承創建了派生類與基類之間的關係,它是一種'是'的關係,好比白馬是馬,人是動物;算法
當類之間有不少相同的功能,提取這些共同的功能作成基類,用繼承比較好,好比老師是人,學生是人;sql
2)組合的方式編程
用組合的方式創建了類與組合的類之間的關係,它是一種‘有’的關係,好比教授有生日,教授教python和linux課程,教授有學生s一、s二、s3...json
示例:繼承與組合網絡
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/16 0016 21:05 # class Teacher:#定義講師類; # school = 'luffycity' # def __init__(self,name,age,sex,level,salary): # self.name = name # self.age = age # self.sex = sex # self.level = level # self.salary = salary # def teach(self): # print('%s is teaching Python course'%self.name) # # #定義學生類; # class Student:#定義學生類; # school = 'luffycity' # def __init__(self,name,age,sex,class_time): # self.name = name # self.age = age # self.sex = sex # self.class_time = class_time # def learn(self): # print('%s is learning Python course'%self.name) "" """ 以上出現了代碼重用的現象,so抽取學生和講師公共的部分,定義People類; """ #定義People類; class People: school = 'luffycity' def __init__(self,name,age,sex): self.name = name self.age = age self.sex = sex class Teacher(People):#經過繼承方式,定義講師類; def __init__(self,name,age,sex,level,salary): super().__init__(name,age,sex) self.level = level self.salary = salary def teach(self): print('%s is teaching Python course'%self.name) #定義學生類; class Student(People):#經過繼承方式,定義學生類; school = 'luffycity' def __init__(self,name,age,sex,class_time): super().__init__(name, age, sex) self.class_time = class_time def learn(self): print('%s is learning Python course'%self.name) #定義課程類; class Course: def __init__(self,course_name,course_price,course_period): self.course_name = course_name self.course_price = course_price self.course_period = course_period #再定義課程信息類; def Tell_info(self): print('課程名《%s》 課程價格《%s》 課程週期《%s》'%(self.course_name,self.course_price,self.course_period)) class Date: def __init__(self,year,month,day): self.year = year self.month = month self.day = day def tell_info(self): print('%s-%s-%s'%(self.year,self.month,self.day)) #經過類實例化,產生對象; teacher1 = Teacher('alex',18,'male',10,3000) teacher2 = Teacher('egon',28,'male',10,3000) python = Course('Python',3000,'3months') linux = Course('Linux',4000,'4months') teacher1.course = python teacher2.course = python print(python) print(teacher1.course) print(teacher2.course) """ <__main__.Course object at 0x000001CD7CF35F98> <__main__.Course object at 0x000001CD7CF35F98> <__main__.Course object at 0x000001CD7CF35F98> """ #teacher1 = Teacher('alex',18,'male',10,3000,'Python',3000,'3months') #teacher2 = Teacher('egon',28,'male',10,3000,'Python',3000,'3months') #如何查看老師課程信息; print(python.course_name) print(python.course_period) print(python.course_price) #等價於以下所示; print(teacher1.course.course_name)#Python print(teacher1.course.course_period)#3months print(teacher1.course.course_price)#3000 #查看老師的課程信息的方法; teacher1.course.Tell_info()#這種方式就叫作組合;課程名《Python》 課程價格《3000》 課程週期《3months》 student1 = Student('張三',28,'female','08:30:00') student1.course1 = python student1.course2 = linux #查看學生的課程信息的方法; student1.course1.Tell_info()#課程名《Python》 課程價格《3000》 課程週期《3months》 student1.course2.Tell_info()#課程名《Linux》 課程價格《4000》 課程週期《4months》 student3 = Student('崔曉昭',28,'male','09:00:00') d = Date(1993,9,11) student3.birth = d student3.birth.tell_info()#1993-9-11 "" """ 小結: 一、#什麼有什麼,便可使用組合的方式進行代碼重用; 二、#什麼是什麼,即便用繼承的方式進行代碼重用; """
1)接口與歸一化設計;
hi boy,給我開個查詢接口。。。此時的接口指的是:本身提供給使用者來調用本身功能的方式\方法、入口,java中的interface使用以下:
=================第一部分:Java 語言中的接口很好的展示了接口的含義: IAnimal.java /* * Java的Interface接口的特徵: * 1)是一組功能的集合,而不是一個功能; * 2)接口的功能用於交互,全部的功能都是public,即別的對象可操做; * 3)接口只定義函數,但不涉及函數實現; * 4)這些功能是相關的,都是動物相關的功能,但光合做用就不適宜放到IAnimal裏面了*/ package com.oo.demo; public interface IAnimal { public void eat(); public void run(); public void sleep(); public void speak(); } =================第二部分:Pig.java:豬」的類設計,實現了IAnnimal接口 package com.oo.demo; public class Pig implements IAnimal{ //以下每一個函數都須要詳細實現 public void eat(){ System.out.println("Pig like to eat grass"); } public void run(){ System.out.println("Pig run: front legs, back legs"); } public void sleep(){ System.out.println("Pig sleep 16 hours every day"); } public void speak(){ System.out.println("Pig can not speak"); } } =================第三部分:Person2.java /* *實現了IAnimal的「人」,有幾點說明一下: * 1)一樣都實現了IAnimal的接口,但「人」和「豬」的實現不同,爲了不太多代碼致使影響閱讀,這裏的代碼簡化成一行,但輸出的內容不同,實際項目中同一接口的同一功能點,不一樣的類實現徹底不同; * 2)這裏一樣是「人」這個類,但和前面介紹類時給的類「Person」徹底不同,這是由於一樣的邏輯概念,在不一樣的應用場景下,具有的屬性和功能是徹底不同的 */ package com.oo.demo; public class Person2 implements IAnimal { public void eat(){ System.out.println("Person like to eat meat"); } public void run(){ System.out.println("Person run: left leg, right leg"); } public void sleep(){ System.out.println("Person sleep 8 hours every dat"); } public void speak(){ System.out.println("Hellow world, I am a person"); } } =================第四部分:Tester03.java package com.oo.demo; public class Tester03 { public static void main(String[] args) { System.out.println("===This is a person==="); IAnimal person = new Person2(); person.eat(); person.run(); person.sleep(); person.speak(); System.out.println("\n===This is a pig==="); IAnimal pig = new Pig(); pig.eat(); pig.run(); pig.sleep(); pig.speak(); } } java中的interface
歸一化的好處在於:
1)歸一化讓使用者無需關心對象的類是什麼,只須要的知道這些對象都具有某些功能就能夠了,這極大地下降了使用者的使用難度;
2)歸一化使得高層的外部使用者能夠不加區分的處理全部接口兼容的對象集合;
就好象linux的泛文件概念同樣,全部東西均可以當文件處理,沒必要關心它是內存、磁盤、網絡仍是屏幕(固然,對底層設計者,固然也能夠區分出「字符設備」和「塊設備」,而後作出針對性的設計:細緻到什麼程度,視需求而定)。
再好比:咱們有一個汽車接口,裏面定義了汽車全部的功能,而後由本田汽車的類,奧迪汽車的類,大衆汽車的類,他們都實現了汽車接口,這樣就好辦了,你們只須要學會了怎麼開汽車,那麼不管是本田,仍是奧迪,仍是大衆咱們都會開了,開的時候根本無需關心我開的是哪一類車,操做手法(函數調用)都同樣;
在python中根本就沒有一個叫作interface的關鍵字,若是非要去模仿接口的概念
能夠藉助第三方模塊:http://pypi.python.org/pypi/zope.interface
也可使用繼承,其實繼承有兩種用途
一:繼承基類的方法,而且作出本身的改變或者擴展(代碼重用):實踐中,繼承的這種用途意義並不很大,甚至經常是有害的。由於它使得子類與基類出現強耦合;
二:聲明某個子類兼容於某基類,定義一個接口類(模仿java的Interface),接口類中定義了一些接口名(就是函數名)且並未實現接口的功能,子類繼承接口類,而且實現接口中的功能;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/16 0016 22:12 #抽象類的概念引入及應用場景; import abc class Animal(metaclass=abc.ABCMeta): @abc.abstractmethod#經過抽象類,來實現標準化; def run(self): pass @abc.abstractmethod def eat(self): pass class People(Animal): # pass#TypeError: Can't instantiate abstract class People with abstract methods eat, run def run(self): print('People is running') def eat(self): print('People is eating')
class Pig(Animal): def run(self): print('People is running') def eat(self): print('People is eating') class Dog(Animal): def run(self): print('People is running') def eat(self): print('People is eating') #類實例化產生對象; peo1 = People() pig1 = Pig() dog1 = Dog() # peo1.eat() pig1.eat() dog1.eat() "" """ People is eating People is eating People is eating 小結: 一、抽象類的本質仍是一個類; 二、抽象類與類仍是有一點兒區別的,抽象類只能被繼承,不能被實例化,功能是爲了規範子類; 三、抽象類的做用是基於繼承演變而來的,作歸一化的好處,把全部的接口都規範起來,下降使用者的使用複雜度; """ #抽象類的概念引入及應用場景; #animal = Animal()#TypeError: Can't instantiate abstract class Animal with abstract methods eat, run
1)多態;
多態指的是一類事物有多種形態,好比:動物有多種形態:人,狗,豬;
文件有多種形態:文本文件,可執行文件;
2)多態性;
一 什麼是多態動態綁定(在繼承的背景下使用時,有時也稱爲多態性);
多態性是指在不考慮實例類型的狀況下使用實例,多態性分爲靜態多態性和動態多態性;
靜態多態性:如任何類型均可以用運算符+進行運算;
動態多態性:以下
peo=People() dog=Dog() pig=Pig() #peo、dog、pig都是動物,只要是動物確定有talk方法 #因而咱們能夠不用考慮它們三者的具體是什麼類型,而直接使用 peo.talk() dog.talk() pig.talk() #更進一步,咱們能夠定義一個統一的接口來使用 def func(obj): obj.talk()
python自己就是支持多態性的,這麼作的好處是什麼呢?
1)增長了程序的靈活性
以不變應萬變,不論對象變幻無窮,使用者都是同一種形式去調用,如func(animal);
2)增長了程序額可擴展性
經過繼承animal類建立了一個新的類,使用者無需更改本身的代碼,仍是用 func(animal)去調用 ;
python程序員一般根據這種行爲來編寫程序。例如,若是想編寫現有對象的自定義版本,能夠繼承該對象;
也能夠建立一個外觀和行爲像,但與它無任何關係的全新對象,後者一般用於保存程序組件的鬆耦合度;
利用標準庫中定義的各類‘與文件相似’的對象,儘管這些對象的工做方式像文件,但他們沒有繼承內置文件對象的方法;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/16 0016 22:43 #多態,同一種事物的多種形態 "" """ 一、水的多種形態; 二、動物的多種形態; 三、文件的多種形態; """ import abc class Animal(metaclass=abc.ABCMeta): #同一類事物:動物 @abc.abstractmethod def talk(self): pass class People(Animal): #動物的形態之一:人 def talk(self): print('say hello') class Dog(Animal): #動物的形態之二:狗 def talk(self): print('say wangwang') class Pig(Animal): #動物的形態之三:豬 def talk(self): print('say aoao') class Cat(Animal):#貓 def talk(self): print('say miaomiao') #多態性-指的是能夠在不考慮對象的類型下而直接使用對象; peo1 = People() dog1 = Dog() pig1 = Pig() cat1 = Cat() peo1.talk() dog1.talk() pig1.talk() cat1.talk() #靜態多態性; #動態多態性; def func(animal): animal.talk() func(peo1) func(pig1) func(dog1) func(cat1) #Python崇尚鴨子類型;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/16 0016 22:55 #鴨子類型引入; class File: def read(self): pass def write(self): pass
class Disk: def read(self): print('disk read') def write(self): print('disk write') class Text: def read(self): print('text read') def write(self): print('text write') disk = Disk() text = Text() disk.read() disk.write() text.read() text.write() #序列類型——列表list、元組tuple、字符串str; l = list([1,2,3]) t = tuple(('a','b')) s = str('hello') print(l.__len__()) print(t.__len__()) print(s.__len__()) #按照原來的方法; def len(obj): return obj.__len__() print(len(l)) print(len(t)) print(len(s))
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/17 0017 14:34 class A: __X=1#_A__x=1,在定義階段就被定義; def __init__(self,name):#self._A__name = name self.__name = name def __foo(self): print('run foo') def bar(self): self.__foo()#self._A__foo() print('from bar') #print(A.__X)#AttributeError: type object 'A' has no attribute '__X' #print(A.__foo)#AttributeError: type object 'A' has no attribute '__foo' a = A('egon') #print(a.__name)#AttributeError: 'A' object has no attribute '__name' print(a.__dict__)#{'_A__name': 'egon'} """ 這種變形的特色: 一、外部沒法直接訪問obj.__AttrName; 二、在類內部是能夠直接使用:obj.AttrName 三、子類沒法覆蓋父類__開頭的屬性; """ class Foo: def __func(self):#_Foo__func print('from foo') class Bar(Foo): def __func(self):#_Bar__func print('from bar') #b = Bar() #b.func() """ 總結這樣的變形須要注意的問題: 一、 """ class B: __x = 1 def __init__(self,name): self.__name = name#類定義階段發生隱藏; #驗證問題1: #print(B._B__x)#1,雖然能正常打印,可是不建議這麼使用,由於這種形式就是Python在作隱藏; #驗證問題2; # B.__y =2 # print(B.__dict__)#{'__module__': '__main__', '_B__x': 1, '__init__': <function B.__init__ at 0x00000216F511C048>, '__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, '__y': 2} # b = B('egon') # print(b.__dict__)#{'_B__name': 'egon'} #print(B.__x)#AttributeError: type object 'B' has no attribute '__x' #驗證問題3: # class A: # def foo(self): # print('A.bar') # def bar(self): # print('A.bar') # self.foo() # class B(A): # def foo(self): # print('B.foo') # # b = B() # b.bar() """ A.bar B.foo """ class A: def __foo(self): print('A.bar') def bar(self): print('A.bar') self.__foo() class B(A): def __foo(self): print('B.foo') b = B() b.bar() """ A.bar A.bar """
1)咱們的身體沒有一處不體現着封裝的概念:你的身體把膀胱尿道等等這些尿的功能隱藏了起來,而後爲你提供一個尿的接口就能夠了(接口就是你的丁丁)你總不能把膀胱掛在身體外面,上廁所的時候就跟別人炫耀:hi,man,你瞅個人膀胱,看看我是怎麼尿的。
2)電視機自己是一個黑盒子,隱藏了全部細節,可是必定會對外提供了一堆按鈕,這些按鈕也正是接口的概念,因此說,封裝並非單純意義的隱藏;
3)快門就是傻瓜相機爲傻瓜們提供的方法,該方法將內部複雜的照相功能都隱藏起來了;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/17 0017 15:15 #封裝數據屬性;明確的區份內外,控制外部對隱藏屬性的操做行爲; class People: def __init__(self,name,age): self.__name = name self.__age = age def tell_info(self): print('Name:<%s> Age:<%s>'%(self.__name,self.__age)) #開通一個接口,可修改name或age 的值; def set_info(self,name,age): if not isinstance(name,str): print('名字必須是字符串類型') return elif not isinstance(age,int): print('年齡必須是數字類型') return self.__name = name self.__age = age p = People('egon',18) p.tell_info()#Name:<egon> Age:<18> p.set_info('EGON',18) p.tell_info()#Name:<EGON> Age:<18> #傳入不合法的值; p.set_info(1993,26)#名字必須是字符串類型 p.tell_info() #封裝方法:隔離複雜度;用傻瓜相機來對比專業單反,來解釋複雜度,對用戶來說,使用特別簡答; class Atm: def __card(self): print('插卡') def __auth(self): print('用戶認證') def __input(self): print('輸入提款金額') def __bill(self): print('打印帳單') def __take_money(self): print('取款') #進行隱藏屬性; def withdraw(self): self.__card() self.__auth() self.__input() self.__bill() self.__take_money() a = Atm() a.withdraw() """ 插卡 用戶認證 輸入提款金額 打印帳單 取款 """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/17 0017 15:40 #封裝帶來的可拓展性;很是的靈活去拓展功能,可是對於使用者來講,是隱藏的; class Room: def __init__(self,name,owner,weight,length,height): self.name = name self.owner = owner self.__weight = weight self.__length = length self.__height = height def tell_area(self): return self.__weight * self.__length * self.__height r = Room('衛生間','alex',10,10,3) r.tell_area() print(r.tell_area())#300 立方米;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/17 0017 18:01 #體質指數(BMI)= 體重(kg)/身高*身高(m) class People: def __init__(self,name,weight,height): self.name = name self.weight = weight self.height = height #定義一個新函數bmi; #添加一個property裝飾器屬性; @property def bmi(self): return self.weight / (self.height ** 2) #實例化產生對象; p = People('tqtl',110,1.85) #以下方法太僵化,重複調用; #p.bmi=p.weight / (p.height ** 2) #print(p.bmi)#32.14024835646457 #直接調用函數; #print(p.bmi())#32.14024835646457,雖然實現了功能,可是由原來的「名詞性質調用」變成了「動詞性質的調用」; #最好的調用方法; print(p.bmi)#32.14024835646457 """ 一、添加了property屬性後,恢復到以前的名詞調用方式,相對於使用print(p.bmi())方式,給用戶的感受沒有發生變化; """ #新增需求,自定義了身高指數 p.height = 1.90 print(p.bmi)#30.470914127423825 #可是不能爲p.bmi屬性賦值,由於他是動態計算出來的,會報錯; #p.bmi = 38 #print(p.bmi)#AttributeError: can't set attribute; #補充property的用法; class People: def __init__(self,name): self.__name = name # @property # def get_name(self): # return self.__name @property#使用property的好處,至關於作了一個假裝,將動詞屬性的調用方式,改成名詞屬性的調用方式; def name(self): return self.__name #爲了實現賦值功能,再次定義; @name.setter def name(self,val): if not isinstance(val,str): print('名稱必須是字符串') return self.__name =val #實現刪除操做; @name.deleter def name(self): print('不容許刪除') #實例化產生對象; p = People('tqtl') #print(p.get_name)#tqtl #新需求,不想讓用戶使用p.get_name,使用者容易形成誤解,怎麼辦?使用property裝飾器; print(p.name)#tqtl #不能直接賦值;p.name = 'TQTL',如何解決?不太經常使用; p.name = 'TQTL' print(p.name)#TQTL,實現了從新賦值操做; #新需求又來了,如何定義刪除功能呢?同上 del p.name#不容許刪除 print(p.name)
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:python3.6.5 # Date:2018/6/17 0017 20:17 "" """ 在類內部定義的函數,分爲兩大類: 1、綁定方法:綁定給誰,就應該由誰來調用,誰來調用,就會把調用者當作第一個參數自動傳入; 1)綁定到對象的方法:在類內定義的沒有被任何裝飾器修飾的; 2)綁定到類的方法:在類內部定義的,被裝飾器classmethod修飾的方法; 2、非綁定方法:沒有自動傳值這麼一說;就類中定義的一個普通工具,對象和類均可以使用;使用staticmethod關鍵字; 非綁定方法:不與類或者對象綁定: """ #實例演示: class Foo: def __init__(self,name): self.name = name def tell(self): print('名字是%s'%self.name) @classmethod def func(cls):#cls = Foo print(cls) @staticmethod#真正意義上的普通函數; def func1(x,y): #return x + y print(x+y) f = Foo('tqtl') # print(Foo.tell)#<function Foo.tell at 0x0000015F867A0D90> # Foo.tell(f)#名字是tqtl # print(f.tell)#名字是tqtl #print(Foo.func)#<bound method Foo.func of <class '__main__.Foo'>> #Foo.func()#<class '__main__.Foo'> #print(Foo)#<class '__main__.Foo'> print(Foo.func1)#<function Foo.func1 at 0x00000276CAC20E18> print(f.func1)#<function Foo.func1 at 0x00000276CAC20E18> Foo.func1(1,2)#3 f.func1(1,3)#4
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 20:37 import settings import hashlib import time class People: def __init__(self,name,age,sex): self.id = self.create_id() self.name = name self.age = age self.sex = sex def tell_info(self):#綁定到對象的方法; print('Name:%s Age:%s Sex:%s'%(self.name,self.age,self.sex)) @classmethod def from_conf(cls): obj = cls( settings.name, settings.age, settings.sex, ) return obj#必定有return返回值; @staticmethod#使用該關鍵字,聲明函數爲基本函數; def create_id(): m = hashlib.md5(str(time.time()).encode('utf-8'))#使用str()方法將時間轉換爲字符串,由於不可變數據類型纔可被hash; return m.hexdigest() #實例化產生對象; p = People('tqtl',18,'male') #綁定給對象,就應該由對象來調用,自動將對象自己當作第一個參數傳入; #p.tell_info() #tell_info(p) #綁定給類,就應該由類來調用,自動將類自己當作第一個參數傳入; p = People.from_conf() p.tell_info()#Name:alex Age:18 Sex:female #非綁定方法,不與類或者對象綁定,誰均可以調用,沒有自動傳值一說; #開始實例化產生對象; p1 = People('egon',18,'male') p2 = People('alex',28,'female') p3 = People('peiqi',38,'female') p4 = People('tqtl',8,'male') print(p1.id)#1ca14d661c87f8cf51e12f0250ea9f14 print(p2.id)#1ca14d661c87f8cf51e12f0250ea9f14 print(p3.id)#1ca14d661c87f8cf51e12f0250ea9f14 print(p4.id)#1ca14d661c87f8cf51e12f0250ea9f14
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 20:57 #經過字符串,映射到對象的屬性; class People: def __init__(self,name,age): self.name = name self.age = age def talk(self): print('%s is talking'%self.name) obj = People('tqtl',18) #print(obj.name)#tqtl #print(obj.talk)#<bound method People.talk of <__main__.People object at 0x000001C1FB49FA20>> #choice = input('>>>:')#choice = 'name' #print(obj.choice)#print(obj.'name')#這麼寫語法錯誤; #hasattr() hasattr(obj,'name')#obj.name print(hasattr(obj,'name'))#True print(hasattr(obj,'talk'))#True getattr(obj,'name') getattr(obj,'name',None) print(getattr(obj,'name'))#tqtl print(getattr(obj,'talk',None))#<bound method People.talk of <__main__.People object at 0x00000133664749B0>> setattr(obj,'sex','male') print(obj.sex)#male delattr(obj,'age') print(obj.__dict__)#{'name': 'tqtl', 'sex': 'male'} #經過字符串來訪問到對象或類的屬性的一種方法; #具體應用場景-反射應用 class Service: def run(self): while True: inp = input('>>>:').strip()#cmd = 'get a.txt' cmds = inp.split()#cmds = ['get','a.txt'] #print(cmds) if hasattr(self,cmds[0]): func = getattr(self,cmds[0]) func(cmds) # cmd = input('>>>').strip() # print(cmd) def get(self,cmds):#下載功能; print('get ...',cmds) def put(self,cmds):#上傳功能; print('put ...',cmds) obj = Service() obj.run() """ >>>:get a.txt get ... ['get', 'a.txt'] >>>:put a.txt put ... ['put', 'a.txt'] >>>: """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 21:20 #item系列; class Foo: def __init__(self,name): self.name = name def __getitem__(self, item): #print('getitem') # print(item) return self.__dict__.get(item) def __setitem__(self, key, value): #print('setitem') #print(key,value) self.__dict__[key] = value def __delitem__(self, key): #print('delitem') #print(key) #self.__dict__.pop() del self.__dict__[key] obj = Foo('tqtl') #查看屬性; #obj['name']#完成obj.name print(obj['namexxxx'])#None #設置屬性; obj.sex = 'male' obj['sex']='male' print(obj.__dict__) print(obj.sex)#male #刪除屬性; #以前的套路: #del obj.name #如今的套路; del obj['name'] print(obj.__dict__)#male """ 小結: 把對象作成一個像字典同樣的對象去操做; 把類定製化成dict類型的東西,進行增刪改查操做; """ d = {'name':'tqtl'} print(isinstance(d,dict))#True #__str__方法; class People: def __init__(self,name,age): self.name =name self.age = age def __str__(self): #print('=====>str')#TypeError: __str__ returned non-string (type NoneType) return '<name:%s,age:%s>'%(self.name,self.age) obj = People('tqtl',26) #print(obj)#<__main__.People object at 0x000001CD512E4BE0> print(obj)#<name:tqtl,age:26> #print語句,打印對咱們有用的信息; #__del__方法;回收系統資源 # f = open(file='settings.py',mode='rb')#本質上是一個賦值操做; # f.read() # f.close()#申請的資源,用完以後,要回收;給操做系統發送信號,回收操做系統資源; # print() class Open: def __init__(self,filename): print('Open file......') self.filename = filename def __del__(self): print('回收操做系統資源:self.close()') f = Open('settings.py') print('----main-----')# """ Open file...... ----main----- 回收操做系統資源:self.close() """
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 22:34 "" """ 知識儲備:exec 一、參數1:字符串形式的命令; 二、參數2:全局做用域(字典形式),若是不指定,默認就使用globals() 三、參數3:局部做用域(字典形式),若是不指定,默認就使用locals() """ # g = { # 'x':1, # 'y':2 # } # l = {} # exec(""" # global x,m # x = 10 # m =100 # # z =3 # """,g,l) # print(g) # print(l) """ C:\\Users\\Administrator\PycharmProjects\LFXC2018\venv\Scripts\python.exe "C:/Users/Administrator/PycharmProjects/LFXC2018/第三模塊 面向對象/27-元類介紹.py" {'x': 10, 'y': 2, '__builtins__': {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\n\nNoteworthy: None is the `nil' object; Ellipsis represents `...' in slices.", '__package__': '', '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': ModuleSpec(name='builtins', loader=<class '_frozen_importlib.BuiltinImporter'>), '__build_class__': <built-in function __build_class__>, '__import__': <built-in function __import__>, 'abs': <built-in function abs>, 'all': <built-in function all>, 'any': <built-in function any>, 'ascii': <built-in function ascii>, 'bin': <built-in function bin>, 'callable': <built-in function callable>, 'chr': <built-in function chr>, 'compile': <built-in function compile>, 'delattr': <built-in function delattr>, 'dir': <built-in function dir>, 'divmod': <built-in function divmod>, 'eval': <built-in function eval>, 'exec': <built-in function exec>, 'format': <built-in function format>, 'getattr': <built-in function getattr>, 'globals': <built-in function globals>, 'hasattr': <built-in function hasattr>, 'hash': <built-in function hash>, 'hex': <built-in function hex>, 'id': <built-in function id>, 'input': <built-in function input>, 'isinstance': <built-in function isinstance>, 'issubclass': <built-in function issubclass>, 'iter': <built-in function iter>, 'len': <built-in function len>, 'locals': <built-in function locals>, 'max': <built-in function max>, 'min': <built-in function min>, 'next': <built-in function next>, 'oct': <built-in function oct>, 'ord': <built-in function ord>, 'pow': <built-in function pow>, 'print': <built-in function print>, 'repr': <built-in function repr>, 'round': <built-in function round>, 'setattr': <built-in function setattr>, 'sorted': <built-in function sorted>, 'sum': <built-in function sum>, 'vars': <built-in function vars>, 'None': None, 'Ellipsis': Ellipsis, 'NotImplemented': NotImplemented, 'False': False, 'True': True, 'bool': <class 'bool'>, 'memoryview': <class 'memoryview'>, 'bytearray': <class 'bytearray'>, 'bytes': <class 'bytes'>, 'classmethod': <class 'classmethod'>, 'complex': <class 'complex'>, 'dict': <class 'dict'>, 'enumerate': <class 'enumerate'>, 'filter': <class 'filter'>, 'float': <class 'float'>, 'frozenset': <class 'frozenset'>, 'property': <class 'property'>, 'int': <class 'int'>, 'list': <class 'list'>, 'map': <class 'map'>, 'object': <class 'object'>, 'range': <class 'range'>, 'reversed': <class 'reversed'>, 'set': <class 'set'>, 'slice': <class 'slice'>, 'staticmethod': <class 'staticmethod'>, 'str': <class 'str'>, 'super': <class 'super'>, 'tuple': <class 'tuple'>, 'type': <class 'type'>, 'zip': <class 'zip'>, '__debug__': True, 'BaseException': <class 'BaseException'>, 'Exception': <class 'Exception'>, 'TypeError': <class 'TypeError'>, 'StopAsyncIteration': <class 'StopAsyncIteration'>, 'StopIteration': <class 'StopIteration'>, 'GeneratorExit': <class 'GeneratorExit'>, 'SystemExit': <class 'SystemExit'>, 'KeyboardInterrupt': <class 'KeyboardInterrupt'>, 'ImportError': <class 'ImportError'>, 'ModuleNotFoundError': <class 'ModuleNotFoundError'>, 'OSError': <class 'OSError'>, 'EnvironmentError': <class 'OSError'>, 'IOError': <class 'OSError'>, 'WindowsError': <class 'OSError'>, 'EOFError': <class 'EOFError'>, 'RuntimeError': <class 'RuntimeError'>, 'RecursionError': <class 'RecursionError'>, 'NotImplementedError': <class 'NotImplementedError'>, 'NameError': <class 'NameError'>, 'UnboundLocalError': <class 'UnboundLocalError'>, 'AttributeError': <class 'AttributeError'>, 'SyntaxError': <class 'SyntaxError'>, 'IndentationError': <class 'IndentationError'>, 'TabError': <class 'TabError'>, 'LookupError': <class 'LookupError'>, 'IndexError': <class 'IndexError'>, 'KeyError': <class 'KeyError'>, 'ValueError': <class 'ValueError'>, 'UnicodeError': <class 'UnicodeError'>, 'UnicodeEncodeError': <class 'UnicodeEncodeError'>, 'UnicodeDecodeError': <class 'UnicodeDecodeError'>, 'UnicodeTranslateError': <class 'UnicodeTranslateError'>, 'AssertionError': <class 'AssertionError'>, 'ArithmeticError': <class 'ArithmeticError'>, 'FloatingPointError': <class 'FloatingPointError'>, 'OverflowError': <class 'OverflowError'>, 'ZeroDivisionError': <class 'ZeroDivisionError'>, 'SystemError': <class 'SystemError'>, 'ReferenceError': <class 'ReferenceError'>, 'BufferError': <class 'BufferError'>, 'MemoryError': <class 'MemoryError'>, 'Warning': <class 'Warning'>, 'UserWarning': <class 'UserWarning'>, 'DeprecationWarning': <class 'DeprecationWarning'>, 'PendingDeprecationWarning': <class 'PendingDeprecationWarning'>, 'SyntaxWarning': <class 'SyntaxWarning'>, 'RuntimeWarning': <class 'RuntimeWarning'>, 'FutureWarning': <class 'FutureWarning'>, 'ImportWarning': <class 'ImportWarning'>, 'UnicodeWarning': <class 'UnicodeWarning'>, 'BytesWarning': <class 'BytesWarning'>, 'ResourceWarning': <class 'ResourceWarning'>, 'ConnectionError': <class 'ConnectionError'>, 'BlockingIOError': <class 'BlockingIOError'>, 'BrokenPipeError': <class 'BrokenPipeError'>, 'ChildProcessError': <class 'ChildProcessError'>, 'ConnectionAbortedError': <class 'ConnectionAbortedError'>, 'ConnectionRefusedError': <class 'ConnectionRefusedError'>, 'ConnectionResetError': <class 'ConnectionResetError'>, 'FileExistsError': <class 'FileExistsError'>, 'FileNotFoundError': <class 'FileNotFoundError'>, 'IsADirectoryError': <class 'IsADirectoryError'>, 'NotADirectoryError': <class 'NotADirectoryError'>, 'InterruptedError': <class 'InterruptedError'>, 'PermissionError': <class 'PermissionError'>, 'ProcessLookupError': <class 'ProcessLookupError'>, 'TimeoutError': <class 'TimeoutError'>, 'open': <built-in function open>, 'quit': Use quit() or Ctrl-Z plus Return to exit, 'exit': Use exit() or Ctrl-Z plus Return to exit, 'copyright': Copyright (c) 2001-2018 Python Software Foundation. All Rights Reserved. Copyright (c) 2000 BeOpen.com. All Rights Reserved. Copyright (c) 1995-2001 Corporation for National Research Initiatives. All Rights Reserved. Copyright (c) 1991-1995 Stichting Mathematisch Centrum, Amsterdam. All Rights Reserved., 'credits': Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information., 'license': Type license() to see the full license text, 'help': Type help() for interactive help, or help(object) for help about object.}, 'm': 100} {'z': 3} Process finished with exit code 0 """ #Python中一切皆對象;對象能夠怎麼使用呢? """ 一、均可以被引用; 二、均可以當作函數的參數傳入; 三、均可以當作容器類的元素; 四、均可以當作函數的返回值; 五、從Python一切皆對象的角度來看,那麼類也是對象; """ #什麼叫元類?! class Foo: pass obj = Foo() print(type(obj))#<class '__main__.Foo'> print(type(Foo))#<class 'type'> class Bar: pass print(type(Bar))#<class 'type'> """ 小結: 一、產生類的類,稱之爲元類,默認所使用class關鍵字定義的類,他們的元類是type; """ #二、定義類的兩種方式; #方式一:class關鍵字; class Chinese: country = "China" def __init__(self,name,age): self.name = name self.age = age def talk(self): print('%s is talking'%self.name) print(Chinese)#<class '__main__.Chinese'> #方式二:type關鍵字 #定義類的三要素;類名、類的基類們,類的名稱空間; class_name = 'Chinese' class_bases = (object,) class_body = """ def __init__(self,name,age): self.name = name self.age = age def talk(self): print('%s is talking'%self.name) """ class_dic = {} exec(class_body,globals(),class_dic) print(class_dic)#{'__init__': <function __init__ at 0x000002BCE6762E18>, 'talk': <function talk at 0x000002BCE86E0A60>} Chinese1=type(class_name,class_bases,class_dic) print(Chinese1)#<class '__main__.Chinese'> obj1 = Chinese1('tqtl',25) print(obj1,obj1.name,obj1.age)#<__main__.Chinese object at 0x0000017351444BA8>tqtl 25
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 23:09 #如何本身定製元類; class Mymeta(type):#自定義元類,要繼承type; def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('類名的首字母必須大寫') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必須有註釋且不能爲空;')#拋出異常; #主動拋出異常關鍵字raise; print(class_dic) #print(class_name)#Chinese # print(class_bases)#(<class 'object'>,) #print(class_dic)#{'__module__': '__main__', '__qualname__': 'Chinese', 'country': 'China', '__init__': <function Chinese.__init__ at 0x0000020E7C740D90>, 'talk': <function Chinese.talk at 0x0000020E7C740A60>} super(Mymeta,self).__init__(class_name,class_bases,class_dic) #class chinese(object,metaclass=Mymeta):#TypeError: 類名的首字母必須大寫 class Chinese(object,metaclass=Mymeta): ''' 這裏是註釋哦,出現了__doc__': '\n 這裏是註釋哦\n ' ''' country = "China" def __init__(self,name,age): self.name = name self.age = age def talk(self): print('%s is talking'%self.name) #Chinese = type(class_name,class_bases,class_dic) #raise TypeError('類型錯誤') """ 小結: 一、自定義元類控制建立類的屬性; """ class Foo: pass print(Foo.__dict__)#{'__module__': '__main__', '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None}
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/17 0017 23:33 "" """ #知識儲備__call__方法; class Foo: def __call__(self,*args,**kwargs): print(self) print(args) print(kwargs) obj = Foo()#() #obj()#{} obj(1,2,3,a=1,b=2,c=4)#{'a': 1, 'b': 2, 'c': 4} #元類內部也應該有一個__call__方法,會在調用Foo時候出發執行; """ class Mymeta(type):#自定義元類,要繼承type; def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('類名的首字母必須大寫') if '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必須有註釋且不能爲空;')#拋出異常; #主動拋出異常關鍵字raise; print(class_dic) super(Mymeta,self).__init__(class_name,class_bases,class_dic) #定製call方法; def __call__(self, *args, **kwargs): print(self) print(args) print(kwargs) print('======>') #第一件事:先造一個空對象obj;obj obj = object.__new__(self) # Chinese.__init__(obj.*args.**kwargs) # 第二件事:初始化obj; self.__init__(obj,*args,**kwargs) #第三件事:返回obj; return obj class Chinese(object,metaclass=Mymeta): ''' 這裏是註釋哦,出現了__doc__': '\n 這裏是註釋哦\n ' ''' country = "China" def __init__(self,name,age): self.name = name self.age = age def talk(self): print('%s is talking'%self.name) obj = Chinese('tqtl',18)#至關於:Chinese.__call__(Chiese,'tqtl',18)#======> obj2 = Chinese('tqtl',age=18)#{'age': 18}#======> #在Chinese('tqtl',18)內部產生三件事; #一、先造出空對象obj; #二、初始化obj; #三、返回obj;
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/18 0018 9:20 #單例模式 #實現方式一: class Mysql: __instance = None def __init__(self): self.host = '127.0.0.1' self.port = 3306 @classmethod def singleton(cls): if not cls.__instance: obj = cls() cls.__instance = obj return cls.__instance def conn(self): pass def execute(self): pass # obj1 = Mysql() # obj2 = Mysql() # obj3 = Mysql() # print(obj1) # print(obj2) # print(obj3) obj1 = Mysql.singleton() obj2 = Mysql.singleton() obj3 = Mysql.singleton() print(obj1 is obj2)#True print(obj1 is obj3) print(obj2 is obj3) #實現方式二:元類的方式 class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): if not class_name.istitle(): raise TypeError('類名首字母必須大寫') elif '__doc__' not in class_dic or not class_dic['__doc__'].strip(): raise TypeError('必須有註釋,且註釋不能爲空') super(Mymeta, self).__init__(class_name,class_bases,class_dic)#繼承父類的屬性; self.__instance=None def __call__(self,*args,**kwargs): if not self.__instance: obj = object.__new__(self) self.__init__(obj) self.__instance=obj #obj = object.__new__(self) #self.__init__(obj,*args,**kwargs) return self.__instance class Mysql(object,metaclass=Mymeta): ''' 連接MySQL老數據 ''' def __init__(self): self.host = '127.0.0.1' self.port = 3306 @classmethod def singleton(cls): if not cls.__instance: obj = cls() cls.__instance = obj return cls.__instance def conn(self): pass def execute(self): pass obj1 = Mysql() obj2 = Mysql() obj3 = Mysql() print(obj1 is obj2 is obj3)#True """ 小結: 一、元類是面向對象當中一個深層次的方法,先定義爲選學內容; """
http://www.cnblogs.com/linhaifeng/articles/7341318.html
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/18 0018 9:56 "" """ 什麼是異常?!異常時錯誤發生的信號,一旦程序發生錯誤,而且程序沒有處理這個錯誤,那個就會拋出異常,而且程序的運行隨之終止; 錯誤分爲兩種: 一、語法錯誤;在程序執行前就要馬上改正過來; 二、邏輯錯誤; """ #No.001-ValueError: invalid literal for int() with base 10: 'cuixiaozhao' #int('cuixiaozhao') #No.002-NameError: name 'name' is not defined #name #No.003-IndexError: list index out of range #list1 = [1,2,3] #list1[1000] #No.004-KeyError: 'name' #dict1 = {} #dict1['name'] #No.005-AttributeError: type object 'Foo' has no attribute 'cxz' #class Foo: # pass #Foo.cxz #No.006-ZeroDivisionError: division by zero #1/0 #No.007-TypeError: 'int' object is not iterable #for i in 3: # print(i) #No.008-ModuleNotFoundError: No module named 'cuixiaozhao' #import cuixiaozhao #No.009-被終止; #import time #time.sleep(1000) """ 一、如何進行異常處理?! 強調1:若是錯誤發生的條件是能夠預知的,此時應該使用if判斷去預防異常; 強調2:若是錯誤發生的條件是不能夠預知的,此時應該使用異常處理機制,try ... except """ try:#表示監測代碼; with open(file='a.txt',mode='r',encoding='utf-8') as f: #next(f) print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') print(next(f),end='') except StopIteration: print('出錯啦!') print('=========>1') print('=========>2') print('=========>3') print('=========>4') print('=========>5')
#!/usr/bin/env python # -*- coding:utf-8 -*- # __Author__:Administrator # Version:Python3.6.5 # Date:2018/6/18 0018 10:21 #異常的多分支;被監測的代碼塊,有可能會拋出異常,有多重可能性,而且咱們須要針對每一種異常類型,都定製專門的處理邏輯; # try: # print('========>1') # #name # print('========>2') # list1 = [1,2,3] # #list1[100] # print('========>3') # dict1 = {} # dict1['name'] # print('========>3') # except NameError as e: # print('-=----------',e)#-=---------- name 'name' is not defined # except IndexError as e: # print('-->',e) # except KeyError as e: # print('---------->',e) #print('繼續執行下一個模塊的代碼;') #萬能異常:Exception:被監測的代碼塊,有可能會拋出異常,有多重可能性,而且咱們須要針對每一種異常類型,都定製專門的處理邏輯; #應用場景:咱們針對全部的異常類型,都只用一種處理邏輯就能夠啦! try: print('========>1') name print('========>2') list1 = [1,2,3] list1[100] print('========>3') dict1 = {} dict1['age'] print('========>4') except Exception as e: print('異常發生啦!',e) print('繼續執行下一個模塊的代碼;') #異常多分支與萬能異常的綜合運用; try: print('========>1') name print('========>2') list1 = [1,2,3] list1[100] print('========>3') dict1 = {} dict1['name'] print('========>3') except NameError as e: print('-=----------',e)#-=---------- name 'name' is not defined except IndexError as e: print('-->',e) except KeyError as e: print('---------->',e) except Exception as e: print('Exception是統一的處理方法',e) print('繼續執行下一個模塊的代碼;') #異常處理的其餘結構; try: print('========>1') name print('========>2') list1 = [1,2,3] list1[100] print('========>3') dict1 = {} dict1['name'] print('========>3') except NameError as e: print('-=----------',e)#-=---------- name 'name' is not defined except IndexError as e: print('-->',e) except KeyError as e: print('---------->',e) except Exception as e: print('Exception是統一的處理方法',e) else: print('在被檢測的代碼沒有發生異常時候執行') finally: print('無論被監測的代碼塊有沒有誤發生異常,都會執行!')#好比打開文件的操做,無論有沒有出錯,都應該使用f.close()進行關閉文件,此時就用到 print('繼續執行下一個模塊的代碼;') #主動出發異常,raise,異常類型(值) class People: def __init__(self,age,name): if not isinstance(name,str): raise TypeError('名字必須傳入str類型') elif not isinstance(age,int): raise TypeError('年齡必須傳入int類型') self.name = name self.age = age #p1 = People(333,18) #p2 = People('cuixiaozhao',18) #p3 = People('lijingping','18') #斷言assert info = {} info['name'] = 'tqtl' #info['age'] = 26 # if 'name' not in info: # raise KeyError('必須有name這個key') # if 'age' not in info: # raise KeyError('必須有age這個key') #assert ('name' in info) and ('age' in info)#取代以上代碼;AssertionError #自定義異常,即自定義類; class MyException(BaseException): def __init__(self,msg): super(MyException,self).__init__() self.msg = msg def __str__(self): return '<%s>'%self.msg raise MyException('我自定義的異常類型哦!')# raise MyException('我自定義的異常類型哦!') #__main__.MyException: <我自定義的異常類型哦!> "" """ 千萬不要把異常處理當作萬能的,不要依賴異常處理; 使用場景: 一、錯誤必定會發生,可是沒法預知,並且不能由於錯誤發生而終止程序的運行,即便用異常處理,進行拋出異常操做; 二、錯誤自己可預知,好比if判斷,不該該使用異常處理; """