習(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)限的校驗問題。