Python面向?qū)ο缶幊讨庋b的藝術你了解嗎
1. 面向?qū)ο缶幊?nbsp;
OOP ( Object Oriented Programming
) 即面向?qū)ο缶幊獭?/strong>
面向?qū)ο缶幊淌且环N 編碼思想 ,或是一種 代碼組織方式 。如同編輯文章時,可以選擇 分段、分節(jié) 的方式讓文章看起來有層次、更方便閱讀或修改。
編碼時可以選擇使用 OOP 方案,也可以選擇不使用。如同行文一樣,使用或不使用都不會對 核心邏輯 產(chǎn)生影響。
面向?qū)ο缶幊逃凶约旱暮诵木幋a理論,對于任何一種計算機語言而言,如果選擇支持此理論, 則稱此計算機語言支持面向?qū)ο缶幊?/strong> 。如 C++、Java、Python……
因每一種計算機語言語法上的差異性,在提供 OOP 實現(xiàn)時的 語法規(guī)范 會有很大的區(qū)別。除此之外,對于每一種語言而言,也可以在 OOP 基礎理論上進行語法擴展或限制。如 Python 支持多繼承。而 Java 語言只支持單根繼承……
1.1 OOP 特點
要了解 OOP 的特點,可從 2 個角度進行闡述。
廣義角度:讓程序像人類解決問題一樣去解決問題,讓程序具有人的思維模式。
人類解決問題時,先是要了解問題域中會涉及到 哪些對象 ,然后再深入了解 每一個對象的特性或功能, 最后再做出相應的決策。
比如:為班級選一名班長。
選班長就是現(xiàn)實世界的一個問題域,如何才能選擇一名符合要求的班長?
1.首先確定此問題中涉及的對象(此處便是班上的所有學生)。
2.然后了解每一個學生的興趣、愛好、性格……以及個人能力等等。
3.從了解的群體中匹配一個符合 班長標準 的學生便可。
面向?qū)ο缶幊讨械?nbsp;對象一詞 ,便是借鑒了現(xiàn)實世界中對象概念。
狹義角度:OOP 編碼為整個程序維護帶來的優(yōu)勢
OOP 組織的代碼可讓程序整體上有高度的可閱讀性,除此之外,最主要的特點是可提高代碼的 復用性、安全性、可擴展性。
任何事情都會 2 面性,OOP 會增加代碼的理解難度。
1.2 OOP 基本概念
OOP 中有兩個很重要的概念, 類和對象 。
對象從何而來?
現(xiàn)實世界中我們很少思考這個問題,在 選班長時 ,不會思考學生是從哪里來的,即使思考這個問題,也會認為那是哲學家的事情。
我們不思考現(xiàn)實世界中的手機、電腦、電視機是怎么來的……因為我們不關心這個,我們關心的是使用它們所提供的功能。
如果我們思考一下手機是怎么出現(xiàn)的,則會發(fā)現(xiàn):
1.首先需要工程師設計手機藍圖。
2.在工廠里根據(jù)手機藍圖進行生產(chǎn)(可能生產(chǎn)很多)。
3.用戶購買手機,了解手機特性和功能,使用手機。
我們身邊的諸如 電視機、洗衣機、電腦……
無不例外的需要經(jīng)過這幾個過程后方能來到我們的世界。
即使是人也是女媧按自己的樣子創(chuàng)建出來的……
同理,電腦世界里不會突然冒出手機、電腦、學生……如何才能讓電腦出現(xiàn)此類對象。一樣,先設計一個藍圖,此藍圖在電腦世界我們就稱其為 “類” 。
有了 “類” 之后才可以 創(chuàng)建手機對象 ,有了對象后才能在程序代碼中使用設計時為手機賦予功能完成程序邏輯。
現(xiàn)實世界設計手機藍圖時,需要設計手機的外觀,如大小、形狀、體重……需要賦予手機功能、如打電話、播放音樂、播放視頻、上網(wǎng)……
在計算機的編碼世界里,同樣在設計類時需要為 “手機類” 設計外觀和功能。 OPP 中稱外觀為屬性,稱功能為方法。
類是藍圖,具有抽象性特征
對象是根據(jù)藍圖創(chuàng)建出來的個體,具有具體性、實用性特征
2. Python 實現(xiàn) OOP
如需使用 OOP 理念實現(xiàn)程序邏輯,則需遵循如下流程:
2.1 分析問題
首先需要明確問題: 如編寫一個程序摸擬小狗的行為。
此問題中的對象便是小狗,所以程序中需要一只小狗。
按上所述,創(chuàng)建小狗之前需要設計“狗類”,因此需要為類的設計提供足夠的信息。
分析可得在設計類時需要有小狗屬性:姓名、年齡,小狗的行為:尊下、打滾。
2.2 類設計語法
class Dog(): def __init__(self, name, age): """初始化屬性name和age""" self.name = name self.age = age def sit(self): """小狗蹲下行為""" print(self.name.title() + " 乖乖的尊下了!") def roll_over(self): """小狗打滾""" print(self.name.title() + " 開始打滾哈!")
如上為 python 中類設計的結構語法:
- 類的函數(shù)稱為方法,方法的第一個參數(shù)須是 self 關鍵字。
- __init__ 方法是必須的,其方法名不得修改。 此方法會在創(chuàng)建對象時被自動調(diào)用,用來初始化對象數(shù)據(jù)。
- self.name 聲明一個對象變量,此變量會保存對象的數(shù)據(jù)。
2.3 創(chuàng)建對象語法
有了類后,方可創(chuàng)建對象,有了對象后方可激活屬性和方法。
my_dog = Dog('小雪', 6) print("小狗的名字:"+my_dog.name.title()+".") print("小狗今年"+str(my_dog.age)+" 歲了")
my_dog.sit() my_dog.roll_over()
創(chuàng)建小狗時,需調(diào)用和 類名相同的方法 ,如上述的 Dog( ) 方法,此方法也叫 構造方法 ,此方法實質(zhì)是調(diào)用了類設計中的 __init__ 方法。所以需要傳遞小狗的具體姓名和年齡初始 name 和 age 變量。
調(diào)用類中的方法時,不需要為方法聲明時的 self 參數(shù)傳遞值。
有了對象后,如需要使用此對象的數(shù)據(jù)時,可使用 . 運算符。如上 my_dog.name 得到小狗的姓名。
當然,在創(chuàng)建小狗后,也可以根據(jù)需要 修改小狗的姓名和年齡。
my_dog.name='小花' my_dog.age=4
同樣,也可以使用 . 運算符調(diào)用類設計時的方法。調(diào)用方法也不需要為第一個參數(shù) self 傳值。
運行結果:
小狗的名字:小雪.
小狗今年6 歲了
小雪 乖乖的尊下了!
小雪 開始打滾哈!
有了類之后,可以根據(jù)此類的設計方案,創(chuàng)建出多個對象。每一個對象有自己的數(shù)據(jù)空間,彼此之間的數(shù)據(jù)是獨立且隔離的。
my_dog = Dog('小黑', 6) your_dog = Dog('小白', 3) print("我的小狗的名字: "+my_dog.name.title()+".") print("我的小狗的年齡 "+str(my_dog.age)+"歲了.") my_dog.sit() print("\n你的小狗的名字: "+your_dog.name.title()+".") print("你的小狗的年齡 "+str(your_dog.age)+" 歲了.") your_dog.sit()
如同現(xiàn)實世界一樣。現(xiàn)在有了 2 只小狗,它們是獨立的個體。修改其中一只狗的名字,對另一只小狗是沒影響的。
我的小狗的名字: 小黑.
我的小狗的年齡 6歲了.
小黑 乖乖的尊下了!
你的小狗的名字: 小白.
你的小狗的年齡 3 歲了.
小白 乖乖的尊下了!
3. OOP 的封裝性
封裝性可以從 2 個角度上展開討論:
3.1 廣義角度:無處不封裝
類就是一個封裝體:它把 數(shù)據(jù) 以及對 數(shù)據(jù)的相關操作 方法封裝在了一起。
方法也是一個封裝體: 封裝了代碼邏輯 。
封裝的優(yōu)點!
當我們通過對象使用 數(shù)據(jù)和方法 時,不需要了解其中的內(nèi)部細節(jié),如此實現(xiàn)了 設計和使用 的分離,和現(xiàn)實世界中我們使用手機一樣,不需了解手機的內(nèi)部結構和細節(jié)。
開發(fā)者在使用 python 提供的模塊時,不需要了解模塊中的相關實現(xiàn)細節(jié),直接使用其功能便可。
設計和使用的分離能加速工業(yè)軟件的開發(fā)效率。
3.2 狹義角度:保證內(nèi)部數(shù)據(jù)的完整性
創(chuàng)建一只小狗后,可以編寫如下代碼修改小狗的年齡。
my_dog = Dog('小雪', 6) my_dog.age=-4
顯然這是不符合實際情況的,沒有一只小狗的年齡可以是負 4 歲。但是,現(xiàn)在程序可以正常運行。
小狗今年-4 歲了
出現(xiàn)這樣不合常理的想象,應該追究誰的責任。 類的設計者還是對象使用者?
我們應該要追究類設計者的責任,就如同我剛買的手機不能充電一樣,是設計者的設計缺陷引起的。
我們應該在設計類的時候提供一種內(nèi)部安全檢查機制,保護 變量 能被賦予一個正確的、可靠的值。
實施流程:
1. 在變量、方法的前面加上雙下劃線(__)讓變量成為私有概念
python 的語法有很大的彈性。添加下劃性只是一種象征性或類似于道德層面的約定。并不能真正意義上讓外部不能訪問。
class Dog(): def __init__(self, name, age): """初始化屬性name和age""" self.name = name #私有化 self.__age = age def sit(self): """小狗蹲下行為""" print(self.name.title() + " 乖乖的尊下了!") def roll_over(self): """小狗打滾""" print(self.name.title() + " 開始打滾哈!")
2. 在類中提供對應的 set 和 get 方法實現(xiàn)對內(nèi)部變量的保護。
def get_age(self): return self.__age # 對數(shù)據(jù)進行檢查 def set_age(self, age): if age<0: print("小狗的年齡不可能為負數(shù)") return self.__age = age
3. 測試
my_dog = Dog('小雪', 6) my_dog.set_age(-4) print("小狗的名字:"+my_dog.name.title()+".") print("小狗今年"+str(my_dog.get_age())+" 歲了")
輸出結果
小狗的年齡不可能為負數(shù)
小狗的名字:小雪.
小狗今年6 歲了
python 還有一種更優(yōu)雅的解決方案。使用注解方式。
class Dog(): def __init__(self, name, age): self.name = name # 私有屬性,屬性名(age)前面雙下劃線的名稱 self.__age = age # 實例方法 def run(self): print("{} 在跑……".format(self.name)) # 使用 @property 定義age屬性的 get 方法 @property def age(self): return self.__age # 使用 @age.setter 定義 age 屬性的 set 方法必須放在@property的后面 @age.setter def age(self, age): if age < 0: print("小狗的年齡不能是負數(shù)") return self.__age = age #實例化小狗 dog = Dog("小紅", 3) print("{0} 狗狗的年齡是 {1}".format(dog.name, dog.age)) #修改年齡 dog.age = -4 print("{0} 狗狗的年齡是 {1}".format(dog.name, dog.age))
輸出結果
小紅 狗狗的年齡是 3
小狗的年齡不能是負數(shù)
小紅 狗狗的年齡是 3
4 . 總結
面向?qū)ο缶幊炭梢杂谩度祟惡喪贰分械囊痪湓捒偨Y,人類文明的進步不一定能澤福到每一個個體。
類可以設計的很完美,但每一個對象作為個體可以有自己的命運。
封裝是面向?qū)ο缶幊汤砟钪凶罨疽彩亲钪匾奶匦?,沒有封裝便沒有后續(xù)的更多。
封裝可能讓我們把相關聯(lián)的數(shù)據(jù)與方法構建成一個邏輯上的整體,也可保護內(nèi)部數(shù)據(jù)的安全性,畢竟 沒有數(shù)據(jù)安全性的程序是沒有意義的。
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內(nèi)容!
相關文章
用Python爬取618當天某東熱門商品銷量數(shù)據(jù),看看大家喜歡什么!
618購物節(jié),準備分析一波購物節(jié)大家都喜歡買什么?本文以某東為例,Python爬取618活動的暢銷商品數(shù)據(jù),并進行數(shù)據(jù)清洗,最后以可視化的方式從不同角度去了解暢銷商品中,名列前茅的商品是哪些?銷售數(shù)據(jù)如何?用戶好評如何?等等,需要的朋友可以參考下2021-06-06python中用logging實現(xiàn)日志滾動和過期日志刪除功能
這篇文章主要介紹了python中用logging實現(xiàn)日志滾動和過期日志刪除功能,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08python數(shù)據(jù)可視化之初探?Seaborn
Seaborn?是一個基于?Matplotlib?的?Python?數(shù)據(jù)可視化庫,它提供了更高級別的接口,使得創(chuàng)建美觀的統(tǒng)計圖形變得非常簡單,在這篇文章中,我們將討論?Seaborn?的基礎使用方法,包括如何創(chuàng)建各種常見的統(tǒng)計圖形2023-07-07Python使用import導入本地腳本及導入模塊的技巧總結
這篇文章主要介紹了Python使用import導入本地腳本及導入模塊的技巧,結合實例形式總結分析了Python使用import導入本地腳本及導入模塊的使用方法及相關操作注意事項,需要的朋友可以參考下2019-08-08