葉子帶你學(xué) Python | (六)類與對象初探

習(xí)題答案

作業(yè)一,代碼如下:

a = "0b1010011010"
print(int(a, 2))

結(jié)果為 “666”。

作業(yè)二:

  • abs() 函數(shù)的返回值沒有被重新賦值給 a
  • int() 函數(shù)默認向下取整而不是四舍五入
  • 沒有使用 return 關(guān)鍵字返回結(jié)果

作業(yè)三,代碼如下:

def ConvertAllToHex(a):
    result = []
    for i in a:
        try:
            result.append(hex(i))
        except TypeError:
            result.append(None)
    return result

類與對象概念

簡單來說,類是一張藍圖,而對象則是通過這張藍圖生產(chǎn)出的產(chǎn)品。

你可以設(shè)計一張藍圖叫做“螺栓圖紙”,然后照著它去生產(chǎn)出很多螺栓。

你也可以在這張藍圖上略加改動,比如將螺紋的深度增大,變成一張新的藍圖。

同樣的,也可以設(shè)計一張藍圖叫做“簡書文章”,在此基礎(chǔ)上生產(chǎn)出很多文章對象。

第一個類

在 Python 中,使用關(guān)鍵字 class 定義類。

讓我們來嘗試著做一個文章的藍圖:

class Article():
    pass

類的名字是 Article,后面的括號在這里可以省略,但為了更深入地學(xué)習(xí)類的特點,建議保留。pass 在這里用作占位符,不然 Python 會認為你定義了一個類,但代碼塊里面是空的,從而報錯。

這是一個空類,沒有什么實際意義,讓我們來定義幾個屬性。

屬性是什么呢?文章的標題、內(nèi)容、點贊量等等。

這些是文章對象的屬性,而不是類的屬性,所以我們不能在類里面直接定義,需要先創(chuàng)建一個方法。

方法是什么呢?發(fā)布文章、更新文章、對文章點贊等等。

這里我們要先創(chuàng)建一個叫做__init__的方法,必須是這個名字,字母兩邊分別加上兩個下劃線。

在類里面,定義方法也使用 def 關(guān)鍵字。換句話說,def 在類中,定義的東西就叫方法,反之則叫做函數(shù),想起來這個名詞了嗎?

class Article():
    def __init__(self):
        self.title = "Python 類與對象"
        self.content = "類是一張藍圖,而對象則是生產(chǎn)出來的產(chǎn)品"
        self.likes_count = 20

等等,self 是啥?在類中,我們定義的所有方法,第一個參數(shù)都必須是 self。其實其它名字也可以,但按照慣例,用 self 最合適。

這個變量的值是對象本身。如果你創(chuàng)建了一個對象 a,那么它的值就是 a 這個對象。

在英語中,self 的含義是”我自己“。

如果你不指定參數(shù) self,定義變量的時候,Python 就不知道這個變量是屬于哪個對象的了。

這個 self 的專業(yè)叫法是“指針”,但 Python 弱化了這一概念,我們可以忽略這一點。

在方法內(nèi)操作對象的屬性時,前面要加 self 和一個英文句點,其它語法與定義變量相同。

剛才我們創(chuàng)建的這個方法會在對象被創(chuàng)建時自動運行,不需要我們手動調(diào)用,是不是很 amazing?我們把這類方法叫做”魔法方法“。

你看到的所有雙下劃線包裹的方法都是魔法方法,它們會在合適的時機被自動調(diào)用。

這個__init__方法還有一個名字叫做“構(gòu)造方法”,顧名思義,告訴 Python 怎么創(chuàng)建新對象用的。

接下來我們將擴充這個類,增加對文章的操作。

class Article():
    def __init__(self):
        self.title = "Python 類與對象"
        self.content = "類是一張藍圖,而對象則是生產(chǎn)出來的產(chǎn)品"
        self.likes_count = 20
    def update(self, title, content):
        self.title = title
        self.content = content
    def likeit(self):
        self.likes_count += 1

我們又定義了兩個方法,用來對文章的內(nèi)容進行更新,以及點贊。

現(xiàn)在,是時候把它變成現(xiàn)實了。

來個對象

創(chuàng)建一個對象:

article1 = Article()

這里的括號是不能省略的。

我們把從類創(chuàng)建對象的操作叫做“實例化”,因為對象是類的一個“實際的例子”,是不是很簡單粗暴?

現(xiàn)在我們想看看這篇文章的內(nèi)容,怎么做呢?

print(article1.content)

在對象后面加上一個點,再寫上要訪問的屬性名稱,就可以獲取到它的屬性了。

對象的屬性可以直接更改,像這樣:

article1.title = "類與對象真不錯"
print(article1.title)

不過我們還是用規(guī)范的方式修改文章吧,調(diào)用它的 update 方法:

article1.update("類與對象真不錯", "讓我們來試試調(diào)用方法")
print(article1.title)
print(article1.content)

是不是有什么東西消失了?self 參數(shù)呢?其實 Python 會自動為我們搞定這個問題,不需要我們操心,當(dāng) self 不存在就好。

寫的不錯,給自己點個贊:

article1.likeit()
print(article1.likes_count)

但是,如果有人不講武德:

article1.likes_count = 0
print(article1.likes_count)

怎么辦?

私有方法和私有屬性

點贊量是我們自己的,不能被別人隨便改。

還好,Python 在設(shè)計之初就考慮到了這個問題,只需要在屬性或者方法的前面加上兩個下劃線,就可以將其設(shè)為私有。

class SafeArticle():
    def __init__(self):
        self.title = "Python 類與對象"
        self.content = "類是一張藍圖,而對象則是生產(chǎn)出來的產(chǎn)品"
        self.__likes_count = 20
    def update(self, title, content):
        self.title = title
        self.content = content
    def likeit(self):
        self.__likes_count += 1
    def __delete(self):
        self.title = ""
        self.content = ""
        self.__likes_count = 0

實例化:

article2 = SafeArticle()

不講武德的人又來了,這次更狠:

article2.delete()
AttributeError: 'SafeArticle' object has no attribute 'delete'

有備而來,我們給防出去了,不錯。

如果你不想這么強硬,只希望告訴一些君子“這是個私有屬性 / 私有方法,別去碰它”,可以只加一個下劃線。Python 不會禁止對它的訪問,但編程規(guī)范會告訴其它人不要使用它。

其實 Python 中沒有絕對的私有,所謂雙下劃線的私有只是把屬性 / 方法改了個名,但強烈不建議大家去訪問對象的私有部分,不然可能會帶來一些很難解決的問題。這里也不會給出具體的操作方法,有興趣的小伙伴自己去查閱資料。

在創(chuàng)建對象時傳參

這個文章類我們已經(jīng)做的差不多了,剩下的工作也就是增加更多的屬性和方法,但用戶開始不樂意了:

為什么不能在發(fā)布文章時就指定標題和內(nèi)容?非要發(fā)布之后再更新?是不是在浪費我的更新次數(shù)?

好,我們來解決這個問題:

class GoodArticle():
    def __init__(self, title, content):
        self.title = title
        self.content = content
        self.__likes_count = 20
    def update(self, title, content):
        self.title = title
        self.content = content
    def likeit(self):
        self.__likes_count += 1
    def __delete(self):
        self.title = ""
        self.content = ""
        self.__likes_count = 0

其實就是給構(gòu)造方法加了幾個參數(shù),在后面設(shè)置對象屬性的時候,將對應(yīng)的屬性設(shè)置好。

article3 = GoodArticle("非常不錯的用戶體驗", "用戶給你的程序設(shè)計點了個超贊")
print(article3.title)
print(article3.content)

完美。

面向?qū)ο笕筇匦?/h1>

封裝

顧名思義,把一些東西打包起來。

如果不使用類與對象,就要把文章的一系列屬性作為變量定義在程序中,把方法變成函數(shù),在函數(shù)里對變量進行操作。

這樣沒辦法實現(xiàn)私有,也不能直接初始化文章的內(nèi)容。

而且,當(dāng)你的文章數(shù)量多起來時,這樣就顯得很麻煩了,每加一篇文章都需要添加很多對應(yīng)的變量。

而對象就是把屬性和方法裝在了一個箱子里,你可以決定箱子里哪些東西可以看,哪些不能看,而且不同箱子里可以有相同的東西,也就是多個對象里可以有相同的屬性名。

像這種把互相關(guān)聯(lián)的東西打包在一起,使其成為一個整體的思想,稱為封裝。

多態(tài)

簡單來說,就是多個對象有相同的屬性或方法。

比如我們有一個“帖子”類,和我們的“文章”類一起,分別創(chuàng)建兩個對象。

帖子和文章都有相同的屬性,比如標題和內(nèi)容,也都有相同的方法,比如點贊、評論和私有的刪除。

同樣的,所有電器都有“功率”這一屬性,也都有“通電”方法;所有食物都有“卡路里”這一屬性,也都有“食用”方法。

如果我們在設(shè)計類的時候做到了多態(tài),只要掌握一個類實例化的對象所具有的屬性和方法,就可以使用其它類實例化的對象來得到相似的結(jié)果。

第三個特性叫做“繼承”,我們后文再講。

課后習(xí)題

作業(yè)一:構(gòu)造方法是什么意思?它的方法名是什么?它和“魔法方法”有什么關(guān)系?

作業(yè)二:假如有一個對象,它有三個屬性,分別是add_update_status__reload,請問這三個屬性在私有性方面有什么異同?

作業(yè)三:請編寫一個帖子類,使用字符串存儲標題和內(nèi)容,使用列表存儲評論,使用兩個整數(shù)分別存儲點贊量和評論量,并實現(xiàn)以下操作對應(yīng)的方法:

  • 點贊帖子
  • 取消點贊
  • 添加評論
  • 刪除評論
  • 刪除帖子(私有)

要求帖子對象在創(chuàng)建時可以直接指定標題和內(nèi)容,點贊量和評論量默認為 0,評論列表為空。

不需要考慮對用戶身份與權(quán)限的校驗問題。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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