面向?qū)ο缶幊淌亲钣行У能浖帉懛椒ㄖ怀T诿嫦驅(qū)ο缶幊讨欣床憔帉懕硎粳F(xiàn)實(shí)世界中的事物和情景的類汰扭,并基于這些類來創(chuàng)建對象。編寫類時福铅,定義一個大類對象都有的通用行為萝毛。基于類創(chuàng)建對象時滑黔,每個對象都自動具備這種通用行為笆包,然后可根據(jù)需要賦予每個對象獨(dú)特的個性。根據(jù)類來創(chuàng)建對象被稱為實(shí)例化略荡,這讓你能夠使用類的示例庵佣。
一、創(chuàng)建和使用類
使用類幾乎可以模擬任何東西汛兜。
1巴粪、創(chuàng)建類
dog.py
class Dog():
"""一次模擬小狗的簡單測試"""
def __init__(self,name,age):
"""初始化屬性name和age"""
self.name = name
self.age = age
def sit(self):
"""模擬小狗被命令時蹲下"""
print(self.name.title() + " is now sitting."
注:
- 根據(jù)約定,首字母大寫的名稱指的是類序无,這個類定義中的括號是空的验毡,因?yàn)槲覀円獜目瞻讋?chuàng)建這個類。
- 三引號引起來的是文檔字符串帝嗡,對這個類的功能進(jìn)行描述晶通。
- 方法
__init__()
是一個特殊的方法,每當(dāng)你根據(jù)類創(chuàng)建新的實(shí)例時哟玷,Python都會自動運(yùn)行它狮辽。開頭和結(jié)尾各有兩個下劃線,旨在避免Python默認(rèn)方法與普通方法發(fā)送名稱沖突巢寡。形參self
必不可少喉脖,還必須位于其他形參的前面。 - 以
self
為前綴的變量都可供類中的所有方法使用抑月。
在Python 2.7中國創(chuàng)建類時树叽,應(yīng)在括號內(nèi)包含單詞object
class ClassName(object):
2、根據(jù)類創(chuàng)建實(shí)例
class Dog():
--snip--
my_dog = Dog('Bob',2)
print("My dog's name is " + my_dog.name.title() +".")
約定:首字母大寫的名稱指的是類谦絮,小寫的名稱指的是根據(jù)類創(chuàng)建的實(shí)例题诵。
① 訪問屬性(句點(diǎn)表示法)
my_dog.name
② 調(diào)用方法(句點(diǎn)表示法)
my_dog.sit()
③ 創(chuàng)建多個實(shí)例
my_dog = Dog('Bob',2)
your_dog = Dog('Mei',3)
二洁仗、使用類和實(shí)例
類編寫好之后,你的大部分時間都將花在使用根據(jù)類創(chuàng)建的實(shí)例上性锭。你需要執(zhí)行的一個重要任務(wù)是修改實(shí)例的屬性赠潦,可以直接修改實(shí)例的屬性,也也可以編寫方法以特定的方式進(jìn)行修改草冈。
1她奥、給屬性指定默認(rèn)值
class Dog():
"""一次模擬小狗的簡單測試"""
def __init__(self,name,age):
"""初始化屬性name和age"""
self.name = name
self.age = age
self.color = 'yellow'
def sit(self):
"""模擬小狗被命令時蹲下"""
print(self.name.title() + " is now sitting."
2、修改屬性的值
① 直接修改屬性的值
要修改屬性的值怎棱,最簡單的方式時通過實(shí)例直接訪問它哩俭,然后修改屬性值。
my_dog.color = 'red'
② 通過方法修改屬性的值
將要修改的值傳遞給一個方法蹄殃,由它在內(nèi)部進(jìn)行修改携茂。
class Dog():
--snip--
def update_color(self,color):
"""修改寵物的顏色"""
self.color = 'color'
③ 通過方法對屬性的值進(jìn)行遞增
有時候需要將屬性值遞增特定的量,而不是將其設(shè)置為全新的值诅岩。
三讳苦、繼承
編寫類時,并非總是要從空白開始吩谦。如果你要編寫的類是一個現(xiàn)成類的特殊版本鸳谜,可使用繼承。一個類繼承另一個類式廷,它將自動獲得另一個類的所有屬性和方法咐扭。原來的類稱為父類(超類),新類稱為子類滑废。子類繼承了其父類的所有屬性和方法蝗肪,同時還可以定義自己的屬性和方法。
1蠕趁、子類的方法 __ init __ ()
class Dog():
--snip--
class BabyDog(Dog):
"""嬰兒狗的特殊之處"""
def __init__(self,name,age):
"""初始化父類的屬性"""
super().__init__(name,age)
注:
- 創(chuàng)建子類時薛闪,父類必須包含在當(dāng)前文件中,且位于子類的前面俺陋。
- 定義子類時豁延,必須在括號內(nèi)指定父類的名稱。方法
__init__()
接受創(chuàng)建父類實(shí)例所需的信息腊状。 -
super()
是一個特殊的函數(shù)诱咏,幫助Python將父類和子類關(guān)聯(lián)起來。
2缴挖、python 2.7中的繼承
- 定義父類時在括號內(nèi)指定object袋狞;
- 函數(shù)
super()
需要兩個實(shí)參:子類名和對象self。
class Dog(object):
def __init__(self,name,age):
--snip--
class BabyDog(Dog):
def __init__(self,name,age):
super(Dog,self).__init__(name,age)
--snip--
3、給子類定義屬性和方法
class Dog():
--snip--
class BabyDog(Dog):
"""嬰兒狗的特殊之處"""
def __init__(self,name,age,mother_name):
"""初始化父類的屬性硕并,再初始化嬰兒狗的特有屬性"""
super().__init__(name,age)
self.mother_name = mother_name
def show_mother_name(self,mother_name):
"""打印嬰兒狗的麻麻的名字"""
print("This baby dog's name is " + self.name +" and it's mother is "
+ self.mother_name + ".")
4法焰、重寫父類的方法
對于父類的方法,只要它不符合子類模擬的實(shí)物的行為倔毙,都可對其進(jìn)行重寫。為此乙濒,可在子類中定義一個與要重寫父類方法同名的方法陕赃。這樣,Python將不會考慮這個父類方法颁股,而只關(guān)注你在子類中定義的響應(yīng)方法么库。
5、將實(shí)例用作屬性
使用代碼模擬實(shí)物時甘有,你可能會發(fā)現(xiàn)自己給類添加的細(xì)節(jié)越來越多:屬性和方法清單以及文件都越來越長诉儒。在這種情況下,可能需要將類的一部分作為一個獨(dú)立的類提取出來亏掀〕婪矗可將大型類拆分成多個協(xié)同工作的小類。
class Car():
--snip--
class Battery():
--snip-
class ElectricCar(Car):
"""電動汽車的獨(dú)特之處"""
def __init__(self,make,modle,year):
super().__init__(make,modle,year)
self.battery = Battery()
在ElectricCar
類中滤愕,添加了一個名為self.battery
的屬性温算,這行代碼讓Python創(chuàng)建一個新的Battery
實(shí)例,并將該實(shí)例存儲在屬性self.battery
中间影。每當(dāng)方法__init__()
被調(diào)用時注竿,都將執(zhí)行該操作。因此現(xiàn)在每個ElectricCar
實(shí)例都包含一個自動創(chuàng)建的Battery
實(shí)例魂贬。
四巩割、導(dǎo)入類
隨著你不斷地給類添加功能,文件可能變得很長付燥,為此宣谈,可將類存儲在模塊中,然后在主程序中導(dǎo)入所需的模塊机蔗。
1蒲祈、導(dǎo)入單個類
dog.py
"""一個可用于表示狗的類"""
class Dog():
--snip--
注:三引號引起來的是模塊級文檔字符串,對該模塊的內(nèi)容進(jìn)行簡單的描述萝嘁。
my_dog.py
from dog import Dog
my_dog = Dog('bob',2)
2梆掸、在一個模塊中存儲多個類
雖然同一個模塊中的類之間應(yīng)存在某種相關(guān)性,但可根據(jù)需要在一個模塊中存儲任意數(shù)量的類牙言。
car.py
"""一組用于表示燃油汽車和電動汽車的類"""
class Car():
--snip--
class Battery():
--snip--
class ElectricCar(Car):
--snip--
3酸钦、從一個模塊中導(dǎo)入多個類
my_cars.py
from car import Car,ElectricCar
4、導(dǎo)入整個模塊
導(dǎo)入整個模塊咱枉,再使用句點(diǎn)表示法訪問需要的類卑硫。由于創(chuàng)建類實(shí)例的代碼都包含模塊名徒恋,因此不會與當(dāng)前文件使用的任何名稱發(fā)生沖突。
import car
my_beetle = car.Car('volkswagen','beetle',2016)
my_tesla = car.ElectricCar('tesla','roadster',2017)
5欢伏、導(dǎo)入模塊中的所有類
from module_name import *
但是入挣,不推薦使用這種導(dǎo)入方法。
6硝拧、在一個模塊中導(dǎo)入另一個模塊
有時候需要將類分散到多個模塊中径筏,一面模塊過大,或在同一個模塊中國存儲不相關(guān)的類障陶。此時滋恬,可能一個模塊的類依賴另一個模塊中的類。
electric_car.py
"""一組可用來表示電動汽車的類"""
from car import Car
class ElectricCar(Car):
--snip--
car.py
"""一個可用來表示汽車的類"""
class Car():
--snip--
my_cars.py
from car import Car
from electric_car import ElectricCar
--snip--
五抱究、類編碼風(fēng)格
- 類名應(yīng)采用駝峰命名法恢氯。即將類名中的每個單詞的首字母都大寫,而不使用下劃線鼓寺。實(shí)例名和模塊名都采用小寫格式勋拟,并在單詞之間加上下劃線。
- 對于每個類侄刽,都應(yīng)緊跟在類定義后面包含一個文檔字符串指黎。這種文檔字符串簡要地描述類的功能,并遵循編寫函數(shù)的文檔字符串時采用的格式約定州丹。每個模塊也都應(yīng)該包含一個文檔字符串醋安,對其中的類可用于做什么進(jìn)行描述。
- 可使用空行來組織代碼墓毒,但不要濫用吓揪。在類中,可使用一個空行來分隔方法所计;而在模塊中柠辞,可使用兩個空行來分隔類。
- 需要同時導(dǎo)入標(biāo)準(zhǔn)庫中的模塊和你編寫的模塊時,先編寫導(dǎo)入標(biāo)準(zhǔn)庫模塊的import語句,再添加一個空行赶舆,然后編寫導(dǎo)入你自己編寫的模塊的import語句。