Python面向?qū)ο缶幊?一)

一、面向?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}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容