面向過程編程和對象編程都是程序設(shè)計思想押框,面向過程程序設(shè)計是將需要實(shí)現(xiàn)的功能流程化列出來岔绸,讓程序依次按照命令執(zhí)行。跟面向過程程序設(shè)計不同橡伞,面向?qū)ο缶幊淌菍F(xiàn)實(shí)中的個體的狀態(tài)和行為抽象化成對象的屬性和方法盒揉,通過對象間的方法進(jìn)行信息處理和通信模擬現(xiàn)實(shí)世界中的實(shí)體交互,高度抽象的設(shè)計思想可以模擬現(xiàn)實(shí)中的情景和需求兑徘,更方便地面對大型程序設(shè)計的需要刚盈。
Python是一門面向?qū)ο缶幊痰恼Z言,其將所有的數(shù)據(jù)類型都視為對象挂脑。其中最重要的概念是類和實(shí)例藕漱。類是為某一個現(xiàn)實(shí)對象創(chuàng)建出的模板欲侮,其包含了該對象所擁有的屬性和方法,通過實(shí)例化對類進(jìn)行個性化設(shè)定便創(chuàng)造出實(shí)例肋联。
1.Class 和 Instance
類是作為對象的模板威蕉,可以在里面設(shè)定公共屬性(類屬性)、實(shí)例屬性(對象屬性)橄仍、構(gòu)造器和方法
class Dog(object):
#類屬性默認(rèn)用大寫命名
CATEGORY = '犬屬'
#構(gòu)造器由__init__命名韧涨,括號內(nèi)包括固定參數(shù)self和實(shí)例屬性
def __init__(self,name,ages):
self.name = name
self.__ages = ages
#方法的括號第一個參數(shù)一定是self,可加其他參數(shù)
def run(self,state):
print("狗兒跑得"+state+"侮繁,我叫"+self.name)
#將屬性復(fù)制功能封裝在函數(shù)中提供了一定的安全性虑粥,并且可以在賦值中添加校準(zhǔn)及其他功能。
def setAges(self,ages):
if type(ages) == int:
self.__ages = ages
else:
print("你輸入的不是數(shù)字宪哩,不能充當(dāng)年齡")
def getAges(self):
return self.__ages
dog = Dog("旺財",12)
print(dog.CATEGORY)
dog.run("慢")
dog.setAges(10)
print(dog.getAges())
結(jié)果為:
>犬屬
>狗兒跑得慢娩贷,我叫旺財
>10
在上面的實(shí)例屬性設(shè)定中出現(xiàn)了__ages
這樣子以雙下劃線開頭的屬性定義,這標(biāo)志著是private變量锁孟,不準(zhǔn)許通過實(shí)例.變量
的方式來讀取彬祖,這種保護(hù)機(jī)制便確保了外部程序沒辦法隨意修改對象內(nèi)部的狀態(tài)。其實(shí)本質(zhì)上解釋器會將該變量名轉(zhuǎn)化為_Dog__ages
在其前面添加上_類名
dog.__ages = 1
# 僅僅是為實(shí)例創(chuàng)建了一個新的屬性而已罗岖,動態(tài)語言確實(shí)可以運(yùn)行時添加屬性
print(dog.getAges())
print(dog.__ages)
# __ages在實(shí)例化時已經(jīng)變成了_Dog__ages
dog._Dog__ages = 13
print(dog.getAges())
結(jié)果是:
>10
>1
>13
注意
:有些時候在類定義中出現(xiàn)了了一個下劃線開的實(shí)例變量名涧至,這樣的實(shí)例變量在程序?qū)用嫔鲜强梢哉TL問的,但是按照約定俗成的規(guī)定桑包,這種命名形式是告訴使用者將其看成私有變量南蓬,不要從外面進(jìn)行訪問。
2.類屬性和實(shí)例屬性
類屬性是指該變量歸類所有哑了,所有新創(chuàng)建的實(shí)例都可以訪問得到赘方,但只能通過類名索引的方式來修改勒邊來那個。Python可以在類定義中用self定義實(shí)例變量弱左,作為動態(tài)語言也可以在程序執(zhí)行過程中通過實(shí)例直接創(chuàng)建實(shí)例變量窄陡。
>>> class Dog():
name = "旺財"
>>> dog = Dog()
# 訪問類變量
>>> dog.name
'旺財'
# 綁定新的實(shí)例屬性
>>> dog.ages = 12
>>> dog.ages
12
# 實(shí)例屬性覆蓋類屬性
>>> dog.name = "耿狗"
>>> dog.name
'耿狗'
# 刪除實(shí)例屬性,重新可以訪問類屬性
>>> del dog.name
>>> dog.name
'旺財'
# 重新定義類屬性
>>> Dog.name = "lal"
>>> Dog.name
'lal'
# 測試是不是真正刪除類屬性
>>> del Dog.name
>>> Dog.name
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
Dog.name
AttributeError: type object 'Dog' has no attribute 'name'
python作為動態(tài)語言可以在運(yùn)行過程中為實(shí)例綁定新的實(shí)例屬性(對類和對其他實(shí)例無效)拆火,如上面所示為Dog實(shí)例dog綁定了新的實(shí)例屬性ages跳夭。有時候我們可能希望限制綁定的屬性,python提供了slots特殊類屬性來限定可動態(tài)綁定的實(shí)例屬性们镜,在類定義的時候?qū)⒖赡苄枰獎討B(tài)綁定的實(shí)例屬性名創(chuàng)建成一個元組賦給slots類屬性币叹,綁定除了指定屬性外的實(shí)例屬性將會出現(xiàn)錯誤。
class Dog(object):
__slots__ = ('name','ages')
dog = Dog()
dog.color = yellow
結(jié)果為:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Dog' object has no attribute 'color'
3.枚舉類與元類
在python中可以用大寫字母來設(shè)定常量模狭,表明不可修改颈抚,但是這并不是一種語言機(jī)制而是一種自覺機(jī)制,有被篡改的風(fēng)險嚼鹉。在python3.4中添加了枚舉類便于大小一定的特殊類的定義贩汉,如季節(jié)驱富、工作日等。
枚舉類有兩種不同的設(shè)定形式匹舞,一種便是按照類定義的形式繼承Enum類褐鸥,可以在類中自定義的設(shè)定每一個成員的具體值,或者可以用Enum函數(shù)直接對每一個成員自動編排值策菜。
from enum import Enum,unique
# 用@unique使枚舉類成員的值都是唯一的
@unique
class Season(Enum):
spring = 1
sunner = 2
autumn = 3
winter = 4
# 可以用Eunm函數(shù)直接定義
Season = Enum('Season',('spring','sunner','autumn','winter'))
其中以枚舉類名.成員名的形式來索引每一個成員晶疼,每一個成員都有其名字和值酒贬,可以調(diào)用枚舉類內(nèi)部的members變量來獲取包含全部成員情況的字典
spring = Season.spring
print(spring.name)
print(spring.value)
for name, member in Season.__members__.items():
print(name, '=>', member, ',', member.value)
輸出:
>spring
>1
>Season.sunner
>spring => Season.spring , 1
>sunner => Season.sunner , 2
>autumn => Season.autumn , 3
>winter => Season.winter , 4
>Season.spring
>Season.sunner
>Season.autumn
>Season.winter
4.繼承與多態(tài)
上面舉的例子Dog類繼承了object類又憨,故object稱為Dog類的Super class,Dog類為Subclass锭吨,子類通過繼承獲得了父類的全部成分蠢莺,并且擁有重新復(fù)寫成分的能力。
class WangCai(Dog):
def __init__(self,state,name,ages):
self.state = state
self.name = name
self.ages = ages
def run(self):
print("我是子類的旺財")
super().run(self.state)
wangcai = WangCai("慢","旺財",12)
wangcai.run()
結(jié)果為:
>我是子類的旺財
>狗兒跑得慢零如,我叫旺財
多態(tài)一般是指在靜態(tài)類型語言中的子類可以傳入需要父類做參數(shù)的函數(shù)躏将,在運(yùn)行的時候調(diào)用子類的相關(guān)內(nèi)容,包含了編譯時類型和運(yùn)行時類型的概念考蕾。這樣一來原先為父類編寫的方法也可以操作子類,而不需要從新定義新的函數(shù)肖卧,大大降低了開發(fā)成本塞帐。但是其實(shí)像python這種動態(tài)類型的語言葵姥,設(shè)定的參數(shù)并不需要提前設(shè)定類型榔幸,參數(shù)引用的對象是具體運(yùn)行到的時候才定義的,因此在實(shí)際操作時可以靈活很多牍疏。只要滿足函數(shù)中所需的調(diào)用的成分麸澜,就可以充當(dāng)參數(shù)傳入并在函數(shù)內(nèi)部進(jìn)行調(diào)用炊邦。這就是動態(tài)語言的“鴨子類型”,它并不要求嚴(yán)格的繼承體系窄俏,一個對象只要“看起來像鴨子碘菜,走起路來像鴨子”忍啸,那它就可以被看做是鴨子。
- 文/潘曉璐 我一進(jìn)店門洞焙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人熔任,你說我怎么就攤上這事唁情∫商Γ” “怎么了甸鸟?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長抢韭。 經(jīng)常有香客問我薪贫,道長篮绰,這世上最難降的妖魔是什么后雷? 我笑而不...
- 正文 為了忘掉前任,我火速辦了婚禮吠各,結(jié)果婚禮上勉抓,老公的妹妹穿的比我還像新娘贾漏。我一直安慰自己纵散,他們只是感情好伍掀,可當(dāng)我...
- 文/花漫 我一把揭開白布蜜笤。 她就那樣靜靜地躺著盐碱,像睡著了一般瓮顽。 火紅的嫁衣襯著肌膚如雪县好。 梳的紋絲不亂的頭發(fā)上,一...
- 文/蒼蘭香墨 我猛地睜開眼禀酱,長吁一口氣:“原來是場噩夢啊……” “哼炬守!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起剂跟,我...
- 序言:老撾萬榮一對情侶失蹤减途,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后曹洽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鳍置,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年送淆,在試婚紗的時候發(fā)現(xiàn)自己被綠了税产。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站谒出,受9級特大地震影響隅俘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜笤喳,卻給世界環(huán)境...
- 文/蒙蒙 一为居、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧杀狡,春花似錦蒙畴、人聲如沸。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至董朝,卻和暖如春鸠项,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背子姜。 一陣腳步聲響...
- 正文 我出身青樓牧抽,卻偏偏與公主長得像嘉熊,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子扬舒,可洞房花燭夜當(dāng)晚...
推薦閱讀更多精彩內(nèi)容
- 面向?qū)ο缶幊?面向?qū)ο缶幊獭狾bject Oriented Programming讲坎,簡稱OOP孕惜,是一種程序設(shè)計思...
- 面向?qū)ο缶幊?面向?qū)ο缶幊獭狾bject Oriented Programming,簡稱OOP晨炕,是一種程序設(shè)計思...
- 在Python中衫画,所有數(shù)據(jù)類型都可以視為對象 變量 - 屬性 函數(shù) - 方法 定義自定義對象(通過 class 關(guān)...