一、面向?qū)ο缶幊?/h2>
1. 面向?qū)ο缶幊毯兔嫦蜻^(guò)程編程的區(qū)別
- 面向過(guò)程編程:機(jī)械思維,簡(jiǎn)化復(fù)雜的流程,可擴(kuò)展性差
- 面向?qū)ο缶幊蹋荷系鬯季S,編程復(fù)雜度高于面向過(guò)程,可擴(kuò)展性強(qiáng)
2. 什么是面向?qū)ο缶幊?/h3>
- 對(duì)象是特征和技能的結(jié)合體
- 創(chuàng)造對(duì)象,給對(duì)象賦予特征和技能,讓對(duì)象干活
- 修改一個(gè)對(duì)象,對(duì)其他地方不影響
- 面向?qū)ο缶幊?,主要解決的是可擴(kuò)展性
3. 類
- 類由對(duì)象組成,是一系列對(duì)象的結(jié)合體,這些對(duì)象具有相似的特征和技能
- 在面向?qū)ο缶幊讨校镜慕嵌炔煌?,分的類不?/li>
- 在現(xiàn)實(shí)世界中現(xiàn)有具體的對(duì)象,才有分類
- 但是在程序中,必須先定義類,后調(diào)用類,來(lái)產(chǎn)生對(duì)象
① 定義類
- 定義類的語(yǔ)法:
class 類的名字:,類的名字使用駝峰語(yǔ)法
類的名字,就是類中名字的容器
類的作用:
- 類當(dāng)做容器,存放類里面的名字
- 調(diào)用類,就會(huì)產(chǎn)生對(duì)象
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
print('=========')
================================執(zhí)行結(jié)果如下======================================
=========
說(shuō)明:類體代碼在類定義階段就會(huì)執(zhí)行,并產(chǎn)生一個(gè)類的名稱空間
② 查看類的名稱空間
類的名字.__dict__
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
print(OldboyStudent.__dict__)
================================執(zhí)行結(jié)果如下======================================
{'__module__': '__main__', 'school': 'oldboy', 'choose_course': <function OldboyStudent.choose_course at 0x0000029B42F7D158>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None}
② 取出類的名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
# 取出類的名稱空間的內(nèi)容
print(OldboyStudent.__dict__['school'])
print(OldboyStudent.__dict__['choose_course'])
OldboyStudent.__dict__['choose_course']('需要寫內(nèi)容') # 調(diào)用類中的函數(shù),但是要加函數(shù)self
================================執(zhí)行結(jié)果如下======================================
oldboy
<function OldboyStudent.choose_course at 0x000001923570D158>
is choosing course
③ 增加查類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
OldboyStudent.country='China' # 相當(dāng)于OldboyStudent.__dict__['country']='China'
print(OldboyStudent.__dict__)
image.png
③ 修改類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
OldboyStudent.country='CHINA'
print(OldboyStudent.__dict__)
image.png
④ 刪除類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
del OldboyStudent.school # 刪除
print(OldboyStudent.__dict__)
⑤ 調(diào)用類
- 語(yǔ)法格式:
類的名字(),調(diào)用類就是產(chǎn)生對(duì)象
- 調(diào)用類的過(guò)程,又稱類的實(shí)例化,實(shí)例化的結(jié)果成為類的對(duì)象或類的實(shí)例
- 調(diào)用類會(huì)獲得一個(gè)返回值,這個(gè)返回值就是類的對(duì)象(實(shí)例)
4. 類的屬性
- 先在現(xiàn)實(shí)世界中總結(jié)對(duì)象(根據(jù)特征和技能),得到現(xiàn)實(shí)世界中的類,再定義為程序中的類,調(diào)用類,產(chǎn)生程序中的對(duì)象(公共類和獨(dú)有對(duì)象)
# 定義類
class OldboyStudent:
# 特征
school='oldboy'
# 技能
def choose_course(self):
print('is choosing course')
# 類屬性的查看類
print(OldboyStudent.school) # OldboyStudent.__dict__['school']
# 類屬性的增加(沒(méi)有的名字)
OldboyStudent.x=1 # OldboyStudent.__dict__['x']=1
# 類屬性的修改(已有的名字)
OldboyStudent.school='Oldboy'
# 類屬性的刪除
del OldboyStudent.x
-
OldboyStudent.a 點(diǎn)后面的名字a稱為屬性,表示在類的名稱空間中找到屬性的值
變量和函數(shù)組成,變量是數(shù)據(jù),函數(shù)是功能
- 類中定義的函數(shù),是類的函數(shù)屬性
- 類中定義的變量,是類的數(shù)據(jù)屬性
class OldboyStudent:
# 特征
school='oldboy'
# 技能
def choose_course(self):
print('is choosing course')
# 類用來(lái)生產(chǎn)對(duì)象,類調(diào)用幾次就生產(chǎn)幾次
stu1=OldboyStudent()
stu2=OldboyStudent()
stu3=OldboyStudent()
print(stu1)
print(stu2)
print(stu3)
==============================執(zhí)行結(jié)果如下===================================
<__main__.OldboyStudent object at 0x000002574C24BDA0>
<__main__.OldboyStudent object at 0x000002574C24BE10>
<__main__.OldboyStudent object at 0x000002574C24BDD8>
# 類產(chǎn)生的對(duì)象,這個(gè)對(duì)象可訪問(wèn)類中的屬性,比如:
# 對(duì)象訪問(wèn)類的屬性和類訪問(wèn)屬性語(yǔ)法一樣
print(OldboyStudent.school)
print(stu1.school) # 作用同上
==============================執(zhí)行結(jié)果如下===================================
oldboy
oldboy
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
# 生產(chǎn)對(duì)象
stu1=OldboyStudent()
stu1.name='itxone'
stu1.age=18
stu1.sex='male'
print(stu1.name,stu1.age,stu1.sex)
==============================執(zhí)行結(jié)果如下===================================
itxone 18 male
5. 為對(duì)象定義獨(dú)有的屬性
- 對(duì)象本身也是名稱空間,即存放自己獨(dú)有的名字的容器,因此,增加對(duì)象的屬性,就是在對(duì)象的名稱空間中增加名字
- 而類中存放的是對(duì)象共有的屬性(數(shù)據(jù)屬性和函數(shù)屬性)
① 查看對(duì)象的名稱空間,默認(rèn)是空的字典
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent()
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{}
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent()
# 添加屬性
stu1.name='itxone'
stu1.age=18
stu1.sex='male'
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'itxone', 'age': 18, 'sex': 'male'}
② 當(dāng)許多對(duì)象都要傳入重復(fù)的name age sex屬性時(shí),就可以將功能,定義到類中
- 添加
__init__方法,表示在調(diào)用類時(shí),會(huì)自動(dòng)觸發(fā)該功能
class OldboyStudent:
school='oldboy'
# 對(duì)象在造出來(lái)的時(shí)候,就帶有對(duì)象的獨(dú)有屬性
def __init__(obj,x,y,z):
obj.name=x
obj.age=y
obj.sex=z
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent('itxone',18,'male')
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'itxone', 'age': 18, 'sex': 'male'}
調(diào)用類時(shí)發(fā)生兩件事:
- 先創(chuàng)建一個(gè)空對(duì)象
stu1
- 然后自動(dòng)觸發(fā)類中的
__init__功能,將對(duì)象stu1和括號(hào)內(nèi)的參數(shù)一起傳入
屬性查找
- 對(duì)象屬性查找順序:先從對(duì)象自己的名稱空間找,再?gòu)念惖拿Q空間中找,如果都沒(méi)有就報(bào)錯(cuò)
-
def __init__(self,x,y,z):中的self是約定俗成寫法,表示傳的是對(duì)象自己
統(tǒng)計(jì)生產(chǎn)了多少次對(duì)象
class OldboyStudent:
school='oldboy'
count=0 # 類中名稱空間的名字
def __init__(self,x,y,z):
self.name=x
self.age=y
self.sex=z
OldboyStudent.count+=1 # 調(diào)用了類中名稱空間的名字,類中的屬性變了,所有的都變了(類的屬性共享)
def choose_course(self):
print('is choosing course')
# 生產(chǎn)對(duì)象
stu1=OldboyStudent('itxone',18,'male')
stu2=OldboyStudent('itxone',18,'male')
stu3=OldboyStudent('itxone',18,'male')
print(OldboyStudent.count)
print(stu1.count)
print(stu2.count)
print(stu3.count)
==============================執(zhí)行結(jié)果如下===================================
3
3
3
3
6. 綁定方法
- 類名稱空間中,定義的數(shù)據(jù)屬性和函數(shù)屬性,都是共享給所有對(duì)象使用的,類中函數(shù)大多是綁定給對(duì)象用的
- 對(duì)象名稱空間中,定義的只有數(shù)據(jù)屬性,而且是對(duì)象獨(dú)有的數(shù)據(jù)屬性
① 類訪問(wèn)類中函數(shù)和對(duì)象訪問(wèn)類中的函數(shù)的區(qū)別
- 類中定義的函數(shù)屬性,類使用這個(gè)函數(shù)屬性,就當(dāng)做普通函數(shù)使用,遵循函數(shù)的參數(shù)規(guī)則
- 而對(duì)象使用類中的函數(shù),是綁定給對(duì)象用的
- 綁定的效果:綁定給哪個(gè)對(duì)象,就由哪個(gè)對(duì)象調(diào)用,并且將這個(gè)綁定對(duì)象作為函數(shù)的第一個(gè)參數(shù)自動(dòng)傳入
- 不同的對(duì)象,可以重復(fù)使用類中的函數(shù),即函數(shù)的功能
class OldboyStudent:
school='oldboy'
count=0
def __init__(self,x,y,z):
self.name=x
self.age=y
self.sex=z
OldboyStudent.count+=1
def choose_course(self): # self就是綁定的對(duì)象,自動(dòng)傳入
print('%s is choosing course' %self.name)
stu1=OldboyStudent('itxone',18,'male')
stu1.choose_course()
print(stu1)
print(stu1.choose_course)
==============================執(zhí)行結(jié)果如下===================================
itxone is choosing course
<__main__.OldboyStudent object at 0x0000028F1966BE10>
<bound method OldboyStudent.choose_course of <__main__.OldboyStudent object at 0x0000028F1966BE10>> # 綁定方法
說(shuō)明:類匯總定義的函數(shù),類可以使用,但是,類定義的函數(shù)大多數(shù)情況下都是綁定對(duì)對(duì)象用的,因此,類中定義的函數(shù)都自帶self參數(shù),表示自動(dòng)傳入綁定的對(duì)象
② 使用綁定方法的優(yōu)點(diǎn):
- 使用綁定方法,不用再重復(fù)輸入相似的代碼,減少了代碼量,節(jié)省內(nèi)存空間
- 對(duì)象的技能就是綁定方法,通過(guò)對(duì)象傳入對(duì)象全部數(shù)據(jù)(傳對(duì)象的名稱空間,比如姓名,年齡等可以一起傳),使類中的函數(shù)可以使用這個(gè)對(duì)象的所有數(shù)據(jù)
- 因此,給一個(gè)對(duì)象,給的是對(duì)象的所有數(shù)據(jù)和處理這些數(shù)據(jù)的綁定方法
class Foo:
pass
obj=Foo() # 創(chuàng)造一個(gè)對(duì)象
print(obj)
==============================執(zhí)行結(jié)果如下===================================
<__main__.Foo object at 0x0000013EAF70A5F8>
③ 自定義的綁定方法和內(nèi)置的綁定方法
- Python3中統(tǒng)一了類與類型的概念,類就是類型,類型就是類
# 自定義的綁定方法
class Foo: # 定義的一個(gè)類
def func(self,x): # 類中的函數(shù)
pass
obj=Foo() # Foo()類,創(chuàng)造了一個(gè)obj的對(duì)象
obj.func(1) # obj.func是綁定方法 相當(dāng)于Foo.func(obj,1)
# 內(nèi)置的綁定方法(以下為偽代碼)
class list: # list是定義的一個(gè)類
def append(self,x): # append的就是類中的函數(shù)
pass
lb=[1,2,3] # 相當(dāng)于lb=list([1,2,3])
lb.append(123) # 綁定方法,相當(dāng)于list.append(lb,123)
小結(jié)
- 對(duì)象是一個(gè)高度整合的產(chǎn)物,整合了數(shù)據(jù)和專門操作該數(shù)據(jù)的方法(綁定方法)
class Foo:
def __init__(self,host,port,db,charset):
self.host=host
self.port=port
self.db=db
self.charset=charset
def excl(self,sql):
conn= connect(self.host,self.port,self.db,self.charset)
conn.execute(sql)
return xxx
# 生產(chǎn)一個(gè)對(duì)象,傳入固定的參數(shù)
obj1=Foo('1.1.1.1',3306,'db1','utf-8')
# 綁定方法只需要傳入一個(gè)參數(shù)就可以,不用重復(fù)傳'1.1.1.1',3306,'db1','utf-8'
obj1.excl('select * from t1')
obj1.excl('select * from t2')
obj1.excl('select * from t3')
# 如果傳入固定的參數(shù)有變動(dòng),在產(chǎn)生一個(gè)對(duì)象即可,節(jié)省了很多代碼
obj2=Foo('10.10.10.10',3307,'db1','utf-8')
obj2.excl('select * from t4')
obj2.excl('select * from t5')
面向?qū)ο蟮奶匦灾唬豪^承和派生
1. 什么是繼承
- 繼承是一種新建類的方式,新建的類稱為子類,被繼承的類稱為父類
- 子類會(huì)具備父類的屬性,子類可以使用父類的功能
- 注意:繼承是類與類之間的關(guān)系
2. 為什么要有繼承
- 繼承的優(yōu)點(diǎn):可以減少代碼的冗余
3. 如何用繼承
- 定義子類的語(yǔ)法:
class 子類名(父類名)
- 在Python中,支持一個(gè)類同時(shí)繼承多個(gè)父類
# 父類
class Parent1:
pass
# 子類
class Sub(Parent1)
pass
# 查看子類繼承關(guān)系
print(Sub1.__bases__)
==============================執(zhí)行結(jié)果如下===================================
(<class '__main__.Parent1'>,)
① Python3和Python2中繼承的區(qū)別
- 在Python3中,如果一個(gè)類沒(méi)有繼承任何類,默認(rèn)繼承
object類
- 在Python2中,如果一個(gè)類沒(méi)有繼承任何類,默認(rèn)不會(huì)繼承
object類
- 新式類:只要是繼承了
object的類以及該類的子類,都是新式類
- 經(jīng)典類:沒(méi)有繼承
object的類以及該類的子類,都是經(jīng)典類
- 在Python3中都是新式類,只有Python2中才區(qū)別新式類與經(jīng)典類
② 繼承多個(gè)父類
class Parent1:
pass
class Parent2:
pass
class Sub1(Parent1,Parent2):
pass
print(Sub1.__bases__)
==============================執(zhí)行結(jié)果如下===================================
(<class '__main__.Parent1'>, <class '__main__.Parent2'>)
4. 尋找繼承關(guān)系的流程
- 找對(duì)象的相似之處,就可以總結(jié)出類,找類相似之處,就可以總結(jié)出父類
- 對(duì)象查找屬性的順序:對(duì)象自己--->對(duì)象的類--->父類--->父類......
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj=Bar()
obj.f2()
==============================執(zhí)行結(jié)果如下===================================
Foo.f2
Bar.f1
5. 子類派生
- 派生:子類中新定義的屬性(技能),子類在使用時(shí),始終以自己的為準(zhǔn)
① 未使用派生
- 未使用派生和繼承,代碼冗余過(guò)多
class OldboyStudent():
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher():
school = 'oldboy'
def __init__(self,name,age,sex,level):
self.name=name
self.age=age
self.sex=sex
self.level=level
def score(self):
print('%s in scoring' %self.name)
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
stu1.choose_course()
tea1.score()
==============================執(zhí)行結(jié)果如下===================================
xut is choosing course
xdw in scoring
② 使用派生方式一
- 在子類派生出新功能中,重用父類功能方式:指定道姓訪問(wèn)一個(gè)類的函數(shù),該方式與繼承無(wú)關(guān)
- 不推薦使用這種派生,如果套的太多就,是強(qiáng)耦合的過(guò)程
# 總結(jié)出共點(diǎn),分出類
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level):
# self.name=name
# self.age=age
# self.sex=sex
# 派生出新的功能,指定道姓訪問(wèn)一個(gè)類的函數(shù)
OldboyPeople.__init__(self,name,age,sex)
self.level=level
def score(self):
print('%s in scoring' %self.name)
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
print(stu1.__dict__)
print(tea1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'xut', 'age': 18, 'sex': 'male'}
{'name': 'xdw', 'age': 18, 'sex': 'male', 'level': 10}
③ 子類派生出來(lái)的功能,不一定和父類有直接關(guān)系
# 總結(jié)出共點(diǎn),分出類
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level):
# self.name=name
# self.age=age
# self.sex=sex
OldboyPeople.__init__(self,name,age,sex)
self.level=level
# 派生打分功能,和父類沒(méi)有直接關(guān)系
def score(self,stu_obj,num):
print('%s in scoring' %self.name)
stu_obj.score=num
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
tea1.score(stu1,99)
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
xdw in scoring
{'name': 'xut', 'age': 18, 'sex': 'male', 'score': 99}
- 面向過(guò)程編程:機(jī)械思維,簡(jiǎn)化復(fù)雜的流程,可擴(kuò)展性差
- 面向?qū)ο缶幊蹋荷系鬯季S,編程復(fù)雜度高于面向過(guò)程,可擴(kuò)展性強(qiáng)
- 對(duì)象是特征和技能的結(jié)合體
- 創(chuàng)造對(duì)象,給對(duì)象賦予特征和技能,讓對(duì)象干活
- 修改一個(gè)對(duì)象,對(duì)其他地方不影響
- 面向?qū)ο缶幊?,主要解決的是可擴(kuò)展性
3. 類
- 類由對(duì)象組成,是一系列對(duì)象的結(jié)合體,這些對(duì)象具有相似的特征和技能
- 在面向?qū)ο缶幊讨校镜慕嵌炔煌?,分的類不?/li>
- 在現(xiàn)實(shí)世界中現(xiàn)有具體的對(duì)象,才有分類
- 但是在程序中,必須先定義類,后調(diào)用類,來(lái)產(chǎn)生對(duì)象
① 定義類
- 定義類的語(yǔ)法:
class 類的名字:,類的名字使用駝峰語(yǔ)法
類的名字,就是類中名字的容器
類的作用:
- 類當(dāng)做容器,存放類里面的名字
- 調(diào)用類,就會(huì)產(chǎn)生對(duì)象
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
print('=========')
================================執(zhí)行結(jié)果如下======================================
=========
說(shuō)明:類體代碼在類定義階段就會(huì)執(zhí)行,并產(chǎn)生一個(gè)類的名稱空間
② 查看類的名稱空間
類的名字.__dict__
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
print(OldboyStudent.__dict__)
================================執(zhí)行結(jié)果如下======================================
{'__module__': '__main__', 'school': 'oldboy', 'choose_course': <function OldboyStudent.choose_course at 0x0000029B42F7D158>, '__dict__': <attribute '__dict__' of 'OldboyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldboyStudent' objects>, '__doc__': None}
② 取出類的名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
# 取出類的名稱空間的內(nèi)容
print(OldboyStudent.__dict__['school'])
print(OldboyStudent.__dict__['choose_course'])
OldboyStudent.__dict__['choose_course']('需要寫內(nèi)容') # 調(diào)用類中的函數(shù),但是要加函數(shù)self
================================執(zhí)行結(jié)果如下======================================
oldboy
<function OldboyStudent.choose_course at 0x000001923570D158>
is choosing course
③ 增加查類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
OldboyStudent.country='China' # 相當(dāng)于OldboyStudent.__dict__['country']='China'
print(OldboyStudent.__dict__)

image.png
③ 修改類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
OldboyStudent.country='CHINA'
print(OldboyStudent.__dict__)

image.png
④ 刪除類名稱空間的內(nèi)容
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
del OldboyStudent.school # 刪除
print(OldboyStudent.__dict__)
⑤ 調(diào)用類
- 語(yǔ)法格式:
類的名字(),調(diào)用類就是產(chǎn)生對(duì)象- 調(diào)用類的過(guò)程,又稱類的實(shí)例化,實(shí)例化的結(jié)果成為類的對(duì)象或類的實(shí)例
- 調(diào)用類會(huì)獲得一個(gè)返回值,這個(gè)返回值就是類的對(duì)象(實(shí)例)
4. 類的屬性
- 先在現(xiàn)實(shí)世界中總結(jié)對(duì)象(根據(jù)特征和技能),得到現(xiàn)實(shí)世界中的類,再定義為程序中的類,調(diào)用類,產(chǎn)生程序中的對(duì)象(公共類和獨(dú)有對(duì)象)
# 定義類
class OldboyStudent:
# 特征
school='oldboy'
# 技能
def choose_course(self):
print('is choosing course')
# 類屬性的查看類
print(OldboyStudent.school) # OldboyStudent.__dict__['school']
# 類屬性的增加(沒(méi)有的名字)
OldboyStudent.x=1 # OldboyStudent.__dict__['x']=1
# 類屬性的修改(已有的名字)
OldboyStudent.school='Oldboy'
# 類屬性的刪除
del OldboyStudent.x
OldboyStudent.a點(diǎn)后面的名字a稱為屬性,表示在類的名稱空間中找到屬性的值
變量和函數(shù)組成,變量是數(shù)據(jù),函數(shù)是功能- 類中定義的函數(shù),是類的函數(shù)屬性
- 類中定義的變量,是類的數(shù)據(jù)屬性
class OldboyStudent:
# 特征
school='oldboy'
# 技能
def choose_course(self):
print('is choosing course')
# 類用來(lái)生產(chǎn)對(duì)象,類調(diào)用幾次就生產(chǎn)幾次
stu1=OldboyStudent()
stu2=OldboyStudent()
stu3=OldboyStudent()
print(stu1)
print(stu2)
print(stu3)
==============================執(zhí)行結(jié)果如下===================================
<__main__.OldboyStudent object at 0x000002574C24BDA0>
<__main__.OldboyStudent object at 0x000002574C24BE10>
<__main__.OldboyStudent object at 0x000002574C24BDD8>
# 類產(chǎn)生的對(duì)象,這個(gè)對(duì)象可訪問(wèn)類中的屬性,比如:
# 對(duì)象訪問(wèn)類的屬性和類訪問(wèn)屬性語(yǔ)法一樣
print(OldboyStudent.school)
print(stu1.school) # 作用同上
==============================執(zhí)行結(jié)果如下===================================
oldboy
oldboy
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
# 生產(chǎn)對(duì)象
stu1=OldboyStudent()
stu1.name='itxone'
stu1.age=18
stu1.sex='male'
print(stu1.name,stu1.age,stu1.sex)
==============================執(zhí)行結(jié)果如下===================================
itxone 18 male
5. 為對(duì)象定義獨(dú)有的屬性
- 對(duì)象本身也是名稱空間,即存放自己獨(dú)有的名字的容器,因此,增加對(duì)象的屬性,就是在對(duì)象的名稱空間中增加名字
- 而類中存放的是對(duì)象共有的屬性(數(shù)據(jù)屬性和函數(shù)屬性)
① 查看對(duì)象的名稱空間,默認(rèn)是空的字典
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent()
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{}
class OldboyStudent:
school='oldboy'
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent()
# 添加屬性
stu1.name='itxone'
stu1.age=18
stu1.sex='male'
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'itxone', 'age': 18, 'sex': 'male'}
② 當(dāng)許多對(duì)象都要傳入重復(fù)的name age sex屬性時(shí),就可以將功能,定義到類中
- 添加
__init__方法,表示在調(diào)用類時(shí),會(huì)自動(dòng)觸發(fā)該功能
class OldboyStudent:
school='oldboy'
# 對(duì)象在造出來(lái)的時(shí)候,就帶有對(duì)象的獨(dú)有屬性
def __init__(obj,x,y,z):
obj.name=x
obj.age=y
obj.sex=z
def choose_course(self):
print('is choosing course')
stu1=OldboyStudent('itxone',18,'male')
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'itxone', 'age': 18, 'sex': 'male'}
調(diào)用類時(shí)發(fā)生兩件事:
- 先創(chuàng)建一個(gè)空對(duì)象
stu1- 然后自動(dòng)觸發(fā)類中的
__init__功能,將對(duì)象stu1和括號(hào)內(nèi)的參數(shù)一起傳入
屬性查找
- 對(duì)象屬性查找順序:先從對(duì)象自己的名稱空間找,再?gòu)念惖拿Q空間中找,如果都沒(méi)有就報(bào)錯(cuò)
def __init__(self,x,y,z):中的self是約定俗成寫法,表示傳的是對(duì)象自己
統(tǒng)計(jì)生產(chǎn)了多少次對(duì)象
class OldboyStudent:
school='oldboy'
count=0 # 類中名稱空間的名字
def __init__(self,x,y,z):
self.name=x
self.age=y
self.sex=z
OldboyStudent.count+=1 # 調(diào)用了類中名稱空間的名字,類中的屬性變了,所有的都變了(類的屬性共享)
def choose_course(self):
print('is choosing course')
# 生產(chǎn)對(duì)象
stu1=OldboyStudent('itxone',18,'male')
stu2=OldboyStudent('itxone',18,'male')
stu3=OldboyStudent('itxone',18,'male')
print(OldboyStudent.count)
print(stu1.count)
print(stu2.count)
print(stu3.count)
==============================執(zhí)行結(jié)果如下===================================
3
3
3
3
6. 綁定方法
- 類名稱空間中,定義的數(shù)據(jù)屬性和函數(shù)屬性,都是共享給所有對(duì)象使用的,類中函數(shù)大多是綁定給對(duì)象用的
- 對(duì)象名稱空間中,定義的只有數(shù)據(jù)屬性,而且是對(duì)象獨(dú)有的數(shù)據(jù)屬性
① 類訪問(wèn)類中函數(shù)和對(duì)象訪問(wèn)類中的函數(shù)的區(qū)別
- 類中定義的函數(shù)屬性,類使用這個(gè)函數(shù)屬性,就當(dāng)做普通函數(shù)使用,遵循函數(shù)的參數(shù)規(guī)則
- 而對(duì)象使用類中的函數(shù),是綁定給對(duì)象用的
- 綁定的效果:綁定給哪個(gè)對(duì)象,就由哪個(gè)對(duì)象調(diào)用,并且將這個(gè)綁定對(duì)象作為函數(shù)的第一個(gè)參數(shù)自動(dòng)傳入
- 不同的對(duì)象,可以重復(fù)使用類中的函數(shù),即函數(shù)的功能
class OldboyStudent:
school='oldboy'
count=0
def __init__(self,x,y,z):
self.name=x
self.age=y
self.sex=z
OldboyStudent.count+=1
def choose_course(self): # self就是綁定的對(duì)象,自動(dòng)傳入
print('%s is choosing course' %self.name)
stu1=OldboyStudent('itxone',18,'male')
stu1.choose_course()
print(stu1)
print(stu1.choose_course)
==============================執(zhí)行結(jié)果如下===================================
itxone is choosing course
<__main__.OldboyStudent object at 0x0000028F1966BE10>
<bound method OldboyStudent.choose_course of <__main__.OldboyStudent object at 0x0000028F1966BE10>> # 綁定方法
說(shuō)明:類匯總定義的函數(shù),類可以使用,但是,類定義的函數(shù)大多數(shù)情況下都是綁定對(duì)對(duì)象用的,因此,類中定義的函數(shù)都自帶
self參數(shù),表示自動(dòng)傳入綁定的對(duì)象
② 使用綁定方法的優(yōu)點(diǎn):
- 使用綁定方法,不用再重復(fù)輸入相似的代碼,減少了代碼量,節(jié)省內(nèi)存空間
- 對(duì)象的技能就是綁定方法,通過(guò)對(duì)象傳入對(duì)象全部數(shù)據(jù)(傳對(duì)象的名稱空間,比如姓名,年齡等可以一起傳),使類中的函數(shù)可以使用這個(gè)對(duì)象的所有數(shù)據(jù)
- 因此,給一個(gè)對(duì)象,給的是對(duì)象的所有數(shù)據(jù)和處理這些數(shù)據(jù)的綁定方法
class Foo:
pass
obj=Foo() # 創(chuàng)造一個(gè)對(duì)象
print(obj)
==============================執(zhí)行結(jié)果如下===================================
<__main__.Foo object at 0x0000013EAF70A5F8>
③ 自定義的綁定方法和內(nèi)置的綁定方法
- Python3中統(tǒng)一了類與類型的概念,類就是類型,類型就是類
# 自定義的綁定方法
class Foo: # 定義的一個(gè)類
def func(self,x): # 類中的函數(shù)
pass
obj=Foo() # Foo()類,創(chuàng)造了一個(gè)obj的對(duì)象
obj.func(1) # obj.func是綁定方法 相當(dāng)于Foo.func(obj,1)
# 內(nèi)置的綁定方法(以下為偽代碼)
class list: # list是定義的一個(gè)類
def append(self,x): # append的就是類中的函數(shù)
pass
lb=[1,2,3] # 相當(dāng)于lb=list([1,2,3])
lb.append(123) # 綁定方法,相當(dāng)于list.append(lb,123)
小結(jié)
- 對(duì)象是一個(gè)高度整合的產(chǎn)物,整合了數(shù)據(jù)和專門操作該數(shù)據(jù)的方法(綁定方法)
class Foo:
def __init__(self,host,port,db,charset):
self.host=host
self.port=port
self.db=db
self.charset=charset
def excl(self,sql):
conn= connect(self.host,self.port,self.db,self.charset)
conn.execute(sql)
return xxx
# 生產(chǎn)一個(gè)對(duì)象,傳入固定的參數(shù)
obj1=Foo('1.1.1.1',3306,'db1','utf-8')
# 綁定方法只需要傳入一個(gè)參數(shù)就可以,不用重復(fù)傳'1.1.1.1',3306,'db1','utf-8'
obj1.excl('select * from t1')
obj1.excl('select * from t2')
obj1.excl('select * from t3')
# 如果傳入固定的參數(shù)有變動(dòng),在產(chǎn)生一個(gè)對(duì)象即可,節(jié)省了很多代碼
obj2=Foo('10.10.10.10',3307,'db1','utf-8')
obj2.excl('select * from t4')
obj2.excl('select * from t5')
面向?qū)ο蟮奶匦灾唬豪^承和派生
1. 什么是繼承
- 繼承是一種新建類的方式,新建的類稱為子類,被繼承的類稱為父類
- 子類會(huì)具備父類的屬性,子類可以使用父類的功能
- 注意:繼承是類與類之間的關(guān)系
2. 為什么要有繼承
- 繼承的優(yōu)點(diǎn):可以減少代碼的冗余
3. 如何用繼承
- 定義子類的語(yǔ)法:
class 子類名(父類名)- 在Python中,支持一個(gè)類同時(shí)繼承多個(gè)父類
# 父類
class Parent1:
pass
# 子類
class Sub(Parent1)
pass
# 查看子類繼承關(guān)系
print(Sub1.__bases__)
==============================執(zhí)行結(jié)果如下===================================
(<class '__main__.Parent1'>,)
① Python3和Python2中繼承的區(qū)別
- 在Python3中,如果一個(gè)類沒(méi)有繼承任何類,默認(rèn)繼承
object類- 在Python2中,如果一個(gè)類沒(méi)有繼承任何類,默認(rèn)不會(huì)繼承
object類- 新式類:只要是繼承了
object的類以及該類的子類,都是新式類- 經(jīng)典類:沒(méi)有繼承
object的類以及該類的子類,都是經(jīng)典類- 在Python3中都是新式類,只有Python2中才區(qū)別新式類與經(jīng)典類
② 繼承多個(gè)父類
class Parent1:
pass
class Parent2:
pass
class Sub1(Parent1,Parent2):
pass
print(Sub1.__bases__)
==============================執(zhí)行結(jié)果如下===================================
(<class '__main__.Parent1'>, <class '__main__.Parent2'>)
4. 尋找繼承關(guān)系的流程
- 找對(duì)象的相似之處,就可以總結(jié)出類,找類相似之處,就可以總結(jié)出父類
- 對(duì)象查找屬性的順序:對(duì)象自己--->對(duì)象的類--->父類--->父類......
class Foo:
def f1(self):
print('Foo.f1')
def f2(self):
print('Foo.f2')
self.f1()
class Bar(Foo):
def f1(self):
print('Bar.f1')
obj=Bar()
obj.f2()
==============================執(zhí)行結(jié)果如下===================================
Foo.f2
Bar.f1
5. 子類派生
- 派生:子類中新定義的屬性(技能),子類在使用時(shí),始終以自己的為準(zhǔn)
① 未使用派生
- 未使用派生和繼承,代碼冗余過(guò)多
class OldboyStudent():
school = 'oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher():
school = 'oldboy'
def __init__(self,name,age,sex,level):
self.name=name
self.age=age
self.sex=sex
self.level=level
def score(self):
print('%s in scoring' %self.name)
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
stu1.choose_course()
tea1.score()
==============================執(zhí)行結(jié)果如下===================================
xut is choosing course
xdw in scoring
② 使用派生方式一
- 在子類派生出新功能中,重用父類功能方式:指定道姓訪問(wèn)一個(gè)類的函數(shù),該方式與繼承無(wú)關(guān)
- 不推薦使用這種派生,如果套的太多就,是強(qiáng)耦合的過(guò)程
# 總結(jié)出共點(diǎn),分出類
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level):
# self.name=name
# self.age=age
# self.sex=sex
# 派生出新的功能,指定道姓訪問(wèn)一個(gè)類的函數(shù)
OldboyPeople.__init__(self,name,age,sex)
self.level=level
def score(self):
print('%s in scoring' %self.name)
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
print(stu1.__dict__)
print(tea1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
{'name': 'xut', 'age': 18, 'sex': 'male'}
{'name': 'xdw', 'age': 18, 'sex': 'male', 'level': 10}
③ 子類派生出來(lái)的功能,不一定和父類有直接關(guān)系
# 總結(jié)出共點(diǎn),分出類
class OldboyPeople:
school='oldboy'
def __init__(self,name,age,sex):
self.name=name
self.age=age
self.sex=sex
class OldboyStudent(OldboyPeople):
def choose_course(self):
print('%s is choosing course' %self.name)
class OldboyTeacher(OldboyPeople):
def __init__(self,name,age,sex,level):
# self.name=name
# self.age=age
# self.sex=sex
OldboyPeople.__init__(self,name,age,sex)
self.level=level
# 派生打分功能,和父類沒(méi)有直接關(guān)系
def score(self,stu_obj,num):
print('%s in scoring' %self.name)
stu_obj.score=num
stu1=OldboyStudent('xut',18,'male')
tea1=OldboyTeacher('xdw',18,'male',10)
tea1.score(stu1,99)
print(stu1.__dict__)
==============================執(zhí)行結(jié)果如下===================================
xdw in scoring
{'name': 'xut', 'age': 18, 'sex': 'male', 'score': 99}