日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

【Python基础】Python 面向对象编程(上篇)

發布時間:2025/3/8 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Python基础】Python 面向对象编程(上篇) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我的施工計劃圖

已完成專題包括:

1我的施工計劃

2數字專題

3字符串專題

4列表專題

5流程控制專題

6編程風格專題

7函數使用專題

今天是面向對象編程的上篇:基礎專題

Python 面向對象編程

面向對象程序設計思想,首先思考的不是程序執行流程,它的核心是抽象出一個對象,然后構思此對象包括的數據,以及操作數據的行為方法。

本專題主要討論面向對象編程(OOP)的基礎和進階知識,實際開發模型中OOP的主要實踐,盡量使用最貼切的例子。

基礎專題

1 類定義

動物是自然界一個龐大的群體,以建模動物類為主要案例論述OOP編程。

Python語言創建動物類的基本語法如下,使用class關鍵字定義一個動物類:

class?Animal():pass

類里面可包括數據,如下所示的Animal類包括兩個數據:self.name和self.speed:

class?Animal():def?__init__(self,name,speed):self.name?=?name?#?動物名字self.speed?=?speed?#?動物行走或飛行速度

注意到類里面通過系統函數__init__為類的2個數據賦值,數據前使用self保留字。

self的作用是指名這兩個數據是實例上的,而非類上的。

同時注意到__init__方法的第一個參數也帶有self,所以也表明此方法是實例上的方法。

2 實例

理解什么是實例上的數據或方法,什么是類上的數據,需要先建立實例的概念,類的概念,如下:

#?生成一個名字叫加菲貓、行走速度8km/h的cat對象 cat?=?Animal('加菲貓',8)?

cat就是Animal的實例,也可以一次創建成千上百個實例,如下創建1000只蜜蜂:

bees?=?[Animal('bee'+str(i),5)?for?i?in?range(1000)]

總結:自始至終只使用一個類Animal,但卻可以創建出許多個它的實例,因此是一對多的關系。

實例創建完成后,下一步打印它看看:

In?[1]:?print(cat)??????????????????????????????????????????????????????????? <__main__.Animal?object?at?0x7fce3a596ad0>

結果顯示它是Animal對象,其實打印結果顯示實例屬性信息會更友好,那么怎么實現呢?

3 打印實例

只需重新定義一個系統(又稱為魔法)函數__str__ ,就能讓打印實例顯示的更加友好:

class?Animal():def?__init__(self,name,speed):self.name?=?name?#?動物名字self.speed?=?speed?#?動物行走或飛行速度def?__str__(self):return?'''Animal({0.name},{0.speed})?is?printedname={0.name}speed={0.speed}'''.format(self)

使用0.數據名稱的格式,這是類專有的打印格式。

現在再打印:

cat?=?Animal('加菲貓',8) print(cat)

打印信息如下:

Animal(加菲貓,8)?is?printedname=加菲貓speed=8

以上就是想要的打印格式,看到實例的數據值都正確。

4 屬性

至此,我們都稱類里的name和speed稱為數據,其實它們有一個專業名稱:屬性。

同時,上面還有一個問題我們沒有回答完全,什么是類上的屬性?

如下,在最新Animal類定義基礎上,再添加一個cprop屬性,它前面沒有self保留字:

class?Animal():cprop?=?"我是類上的屬性cprop"def?__init__(self,name,speed):self.name?=?name?#?動物名字self.speed?=?speed?#?動物行走或飛行速度def?__str__(self):return?'''Animal({0.name},{0.speed})?is?printedname={0.name}speed={0.speed}'''.format(self)

類上的屬性直接使用類便可引用:

In?[1]:?Animal.cprop??????????????????????????????????????????????????????????? Out[1]:?'我是類上的屬性cprop'

類上的屬性,實例同樣可以引用,并且所有的實例都共用此屬性值:

In?[1]:?cat?=?Animal('加菲貓',8) In?[2]:?cat.cprop?????????????????????????????????????????????????????????????? Out[2]:?'我是類上的屬性cprop'

Python作為一門動態語言,支持屬性的動態添加和刪除。

如下cat實例原來不存在color屬性,但是賦值時不光不會報錯,相反會直接將屬性添加到cat上:

cat.color?=?'grap'

那么,如何驗證cat是否有color屬性呢?使用內置函數hasattr:

In?[24]:?hasattr(cat,'color')?#?cat?已經有`color`屬性?????????????????????????? Out[24]:?True

但是注意:以上添加屬性方法僅僅為cat實例本身添加,而不會為其他實例添加:

In?[26]:?monkey?=?Animal('大猩猩',2)???????????????????????????????????????????? In?[27]:?hasattr(monkey,'color')????????????????????????????????????????????? Out[27]:?False

monkey實例并沒有color屬性,注意與__init__創建屬性方法的區別。

5 private,protected,public

像name和speed屬性,引用此實例的對象都能訪問到它們,如下:

#?模塊名稱:manager.pyimport?timeclass?Manager():def?__init__(self,animal):self.animal?=?animaldef?recordTime(self):self.__t?=?time.time()print('feeding?time?for?%s(行走速度為:%s)?is?%.0f'%(self.animal.name,self.animal.speed,self.__t))def?getFeedingTime(self):return?'%0.f'%(self.__t,)?

使用以上Manager類,創建一個cat實例,xiaoming實例引用cat:

cat?=?Animal('加菲貓',8) xiaoming?=??Manager(cat)?

xiaoming的recordTime方法引用里,引用了animal的兩個屬性name和speed:

In[1]:?xiaoming.recordTime()Out[1]:?feeding?time?for?加菲貓(行走速度為:8)?is?1595681304

注意看到self.__t屬性,它就是一個私有屬性,只能被Manager類內的所有方法引用,如被方法getFeedingTime方法引用。但是,不能被其他類引用。

如果我們連speed這個屬性也不想被其他類訪問,那么只需將self.speed修改為self.__speed:

同時Manager類的self.animal.speed修改為self.animal.__speed,再次調用下面方法時:

xiaoming.recordTime()

就會報沒有__speed屬性的異常,從而驗證了__speed屬性已經變為類內私有,不會暴露在外面。

總結:name屬性相當于java的public屬性,而__speed相當于java的private屬性。

下面在說繼承時,講解protected屬性,實際上它就是帶有1個_的屬性,它只能被繼承的類所引用。

6 繼承

上面已經講完了OOP三大特性中的封裝性,而繼承是它的第二大特性。子類繼承父類的所有public和protected數據和方法,極大提高了代碼的重用性。

如上創建的Animal類最新版本為:

class?Animal():cprop?=?"我是類上的屬性cprop"def?__init__(self,name,speed):self.name?=?name?#?動物名字self.__speed?=?speed?#?動物行走或飛行速度def?__str__(self):return?'''Animal({0.name},{0.__speed})?is?printedname={0.name}speed={0.__speed}'''.format(self)

現在有個新的需求,要重新定義一個Cat貓類,它也有name和speed兩個屬性,同時還有color和genre兩個屬性,打印時只需要打印name和speed兩個屬性就行。

因此,基本可以復用基類Animal,但需要修改__speed屬性為受保護(protected)的_speed屬性,這樣子類都可以使用此屬性,而外部還是訪問不到它。

綜合以上,Cat類的定義如下:

class?Cat(Animal):def?__init__(self,name,speed,color,genre):super().__init__(name,speed)self.color?=?color?self.genre?=?genre

首先使用super()方法找到Cat的基類Animal,然后引用基類的__init__方法,這樣復用基類的方法。

使用Cat類,打印時,又復用了基類的 __str__方法:

jiafeimao?=?Cat('加菲貓',8,'gray','CatGenre') print(jiafeimao)

打印結果:

Animal(加菲貓,8)?is?printedname=加菲貓speed=8

以上就是基本的繼承使用案例,繼承要求基類定義的數據和行為盡量標準、盡量精簡,以此提高代碼復用性。

7 多態

如果說OOP的封裝和繼承使用起來更加直觀易用,那么作為第三大特性的多態,在實踐中真正運用起來就不那么容易。有的讀者OOP編程初期,可能對多態的價值體會不深刻,甚至都已經淡忘它的存在。

那么問題就在:多態到底真的有用嗎?到底使用在哪些場景?

多態價值很大,使用場景很多,幾乎所有的系統或軟件,都能看到它的應用。這篇文章盡可能通過一個精簡的例子說明它的價值和使用方法。如果不用多態,方法怎么寫;使用多態,又是怎么寫。

為了一脈相承,做到一致性,仍然基于上面的案例,已經創建好的Cat類要有一個方法打印和返回它的爬行速度。同時需要再創建一個類Bird,要有一個方法打印和返回它的飛行速度;

如果不使用多態,為Cat類新增一個方法:

class?Cat(Animal):def?__init__(self,name,speed,color,genre):super().__init__(name,speed)self.color?=?color?self.genre?=?genre#?添加方法def?getRunningSpeed(self):print('running?speed?of?%s?is?%s'?%(self.name,?self._speed))return?self._speed

重新創建一個Bird類:

class?Bird(Animal):def?__init__(self,name,speed,color,genre):super().__init__(name,speed)self.color?=?color?self.genre?=?genre#?添加方法def?getFlyingSpeed(self):print('flying?speed?of?%s?is?%s'?%(self.name,?self._speed))return?self._speed

最后,上面創建的Manager類會引用Cat和Bird類,但是需要修改recordTime方法,因為Cat它是爬行的,Bird它是飛行的,所以要根據對象類型的不同做邏輯區分,如下所示:

#?模塊名稱:manager.pyimport?time from?animal?import?(Animal,Cat,Bird)class?Manager():def?__init__(self,animal):self.animal?=?animaldef?recordTime(self):self.__t?=?time.time()if?isinstance(self.animal,?Cat):print('feeding?time?for?%s?is?%.0f'%(self.animal.name,self.__t))self.animal.getRunningSpeed()if?isinstance(self.animal,Bird):print('feeding?time?for?%s?is?%.0f'%(self.animal.name,self.__t))self.animal.getFlyingSpeed()def?getFeedingTime(self):return?'%0.f'%(self.__t,)?

如果再來一個類,我們又得需要修改recordTime,再增加一個if分支,從軟件設計角度講,這種不斷破壞封裝的行為不可取。

但是,使用多態,就可以保證recordTime不被修改,不必寫很多if分支。怎么來實現呢?

首先,在基類Animal中創建一個基類方法,然后Cat和Bird分別重寫此方法,最后傳入到Manager類的animal參數是什么類型,在recordTime方法中就會對應調用這個animal實例的方法,這就是多態

代碼如下:

animal2.py 模塊如下:

#?animal2.py?模塊class?Animal():cprop?=?"我是類上的屬性cprop"def?__init__(self,name,speed):self.name?=?name?#?動物名字self._speed?=?speed?#?動物行走或飛行速度def?__str__(self):return?'''Animal({0.name},{0._speed})?is?printedname={0.name}speed={0._speed}'''.format(self)def?getSpeedBehavior(self):pass?class?Cat(Animal):def?__init__(self,name,speed,color,genre):super().__init__(name,speed)self.color?=?color?self.genre?=?genre#?重寫方法def?getSpeedBehavior(self):print('running?speed?of?%s?is?%s'?%(self.name,?self._speed))return?self._speedclass?Bird(Animal):def?__init__(self,name,speed,color,genre):super().__init__(name,speed)self.color?=?color?self.genre?=?genre#?重寫方法def?getSpeedBehavior(self):print('flying?speed?of?%s?is?%s'?%(self.name,?self._speed))return?self._speed

manager2.py 模塊如下:

#?manager2.py?模塊import?time from?animal2?import?(Animal,Cat,Bird)class?Manager():def?__init__(self,animal):self.animal?=?animaldef?recordTime(self):self.__t?=?time.time()print('feeding?time?for?%s?is?%.0f'%(self.animal.name,self.__t))self.animal.getSpeedBehavior()def?getFeedingTime(self):return?'%0.f'%(self.__t,)??

recordTime方法非常清爽,不需要任何if邏輯,只需要調用我們定義的Animal類的基方法getSpeedBehavior即可。

在使用上面所有類時,Manager(jiafeimao)傳入Cat類實例時,recordTime方法調用就被自動指向Cat實例的getSpeedBehavior方法;

Manager(haiying)傳入Bird類實例時,自動指向Bird實例的getSpeedBehavior方法,這就是多態和它的價值,Manager類的方法不必每次都修改,保證了類的封裝性。

if?__name__?==?"__main__":jiafeimao?=?Cat('jiafeimao',2,'gray','CatGenre')haiying?=?Bird('haiying',40,'blue','BirdGenre')Manager(jiafeimao).recordTime()print('#'*30)Manager(haiying).recordTime()??

總結

以上就是面向對象編程專題的基礎部分,大綱如下:

  • Python 面向對象編程

  • 基礎專題

    • 1 類定義

    • 2 實例

    • 3 打印實例

    • 4 屬性

    • 5 private,protected,public

    • 6 繼承

    • 7 多態

  • 總結

往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯獲取一折本站知識星球優惠券,復制鏈接直接打開:https://t.zsxq.com/662nyZF本站qq群1003271085。加入微信群請掃碼進群(如果是博士或者準備讀博士請說明):

總結

以上是生活随笔為你收集整理的【Python基础】Python 面向对象编程(上篇)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。