面向?qū)ο?/h1>
什么是面向?qū)ο螅?/h3>
面向?qū)ο髸r一種思想,是基于面向過程的窑邦。
面向過程:面向過程需要程序員自己處理每一步的操作擅威,就像是炒菜一樣,需要準備好各種蔬菜冈钦,洗菜郊丛,切菜,打開煤氣灶瞧筛,放上鍋宾袜,倒油。驾窟。庆猫。等等,直到菜出鍋你都要知道绅络,都要自己操作月培。
面向?qū)ο?/strong>:如果用面向?qū)ο髞砻枋龀床藨?yīng)該是這樣的。你要炒菜恩急,但是你不會杉畜,你不會不要緊,你有錢是個壕衷恭,你找到一個廚師此叠,對他說你要吃滿漢全席。廚師走了随珠,忙了一個中午灭袁,回來告訴你滿漢全席做好了,可以用膳了窗看。
從上面的兩種炒菜方式可以看出來面向過程注重的內(nèi)部細節(jié)(炒菜的整個流程)茸歧,面向?qū)ο笞⒅氐氖墙Y(jié)果(菜炒出來了就行,怎么炒的我不關(guān)心)显沈。
面向?qū)ο髸r基于面向過程的怎么理解软瞎?
還是用上面的炒菜來說明一下逢唤,現(xiàn)在我是壕,你是廚師涤浇,我不會做菜可以鳖藕,因為我是壕。你不會做菜不可以只锭,你不會做菜你還是廚師嗎吊奢?你是廚師,所以你會做菜纹烹。那么作為廚師你就需要知道怎么洗菜页滚,切菜,打開煤氣铺呵。裹驰。。片挂。等等幻林。
面向過程和面向?qū)ο笫敲懿豢煞值摹?/p>
類
光說面向?qū)ο螅瑢ο笫巧兑裟睿磕睦飦淼幕龋空f到這就需要提到另一個概念 類
什么是類?
人以類聚,物以群分闷愤。類整葡,類似,相似讥脐。程序中的類就是把一些就有相似功能的方法和屬性放到一起遭居,組成的一個小的功能集合,就叫做類旬渠,類是抽象的俱萍。
類的定義
定義格式
class 類名: # class關(guān)鍵字
方法列表
類的構(gòu)成
類名
屬性
方法
class People: # 創(chuàng)建一個類
pass
對象
什么是對象?
面向?qū)ο蟾娑诔绦蛑卸际乾F(xiàn)有類后又對象的枪蘑,為什么呢?因為對對象是類的一個具體存在岖免。就像你岳颇,你是人類,是人類的一個具體的存在觅捆,具體的實例赦役,所以一個類的具體的實例又叫做實例對象麻敌。同理栅炒,對象的方法以及屬性,分別叫做實例方法以及實例屬性。
創(chuàng)建實例對象
創(chuàng)建對象的過程:
class People: # 首先創(chuàng)建一個類
pass
# 創(chuàng)建類的一個實例赢赊,也就是對象乙漓,為了方便使用對象,將對象賦值給變量dragon_fang
dragon_fang = People()
對象的實例屬性和實例方法
人類有一些特征释移,比如姓名叭披、年齡、性別等玩讳。除了這些特征涩蜘,人類還有很多行為,比如可以思考熏纯、可以奔跑同诫、可以吃飯等。
這些描述性的特征就是一個對象的屬性樟澜,而行為動作就是對象的方法误窖。
class People:
def cogitate(self):
print("認真思考。秩贰。霹俺。")
def run(self):
print("可以跑步。毒费。丙唧。")
def eat(self):
print("可以吃飯。觅玻。艇棕。")
dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100
print("name:%s ,age:%d " % (dragon_fang.name, dragon_fang.age))
dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()
通過 對象.屬性 的方式可以直接為對象添加一個屬性或者使用屬性的值,對象.方法()的方式可以直接調(diào)用對象的方法串塑。
self 形參沼琉,self 是一個形參,代表了調(diào)用方法的對象桩匪。雖然形參是可以任意命名的打瘪,但是為了規(guī)
范,這里建議使用self傻昙。
self 的使用
既然self 是實例對象的引用闺骚,name可不可以在實例方法中通過self 獲取實例對象的實例屬性?答案是可以的
class People:
def cogitate(self):
print("認真思考妆档。僻爽。。")
def run(self):
print("可以跑步贾惦。胸梆。敦捧。")
def eat(self):
print("可以吃飯。碰镜。兢卵。")
def show(self): # 增加自我介紹方法
print("name:%s ,age:%d " % (self.name, self.age))
dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100
dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()
dragon_fang.show()
# 結(jié)果:
# 認真思考。绪颖。秽荤。
# 可以跑步。柠横。窃款。
# 可以吃飯。牍氛。雁乡。
# name:DragonFang ,age:100 # show()方法正常執(zhí)行了
創(chuàng)建多個對象
class People:
def cogitate(self):
print("認真思考。糜俗。踱稍。")
def run(self):
print("可以跑步。悠抹。珠月。")
def eat(self):
print("可以吃飯。楔敌。啤挎。")
dragon_fang = People()
dragon_fang.name = "DragonFang"
dragon_fang.age = 100
print("name:%s ,age:%d " % (dragon_fang.name, dragon_fang.age))
dragon_fang.cogitate()
dragon_fang.run()
dragon_fang.eat()
xiao_ming = People() # 創(chuàng)建另一個People類的對象,賦值給xiao_ming
# 創(chuàng)建了xiao_ming 打印一下xiao_ming 的屬性
print("name:%s ,age:%d " % (xiao_ming.name, xiao_ming.age))
結(jié)果信息:
22行報錯卵凑,People 類沒有屬性 name 庆聘。創(chuàng)建第一個對象的時候添加了屬性,dragon_fang 的屬性可以正常使用勺卢, 創(chuàng)建第二個對象的時候說沒有 name 屬性伙判,說明了什么? 說明對象的屬性是各自獨立的黑忱,不共享的宴抚。
魔法方法
魔法方法 _init_(self)
python官方提供了很多的魔法方法,魔法方法在恰當(dāng)?shù)臅r機甫煞,會自動執(zhí)行菇曲。_init(self) 就是其中之一,注意魔法方法兩側(cè)各有兩條下劃線 “_” 抚吠,_init(self) 方法也是一樣常潮。(附官方說明:Called after the instance has been created (by new()), but before it is returned to the caller.)
_init(self) 方法的作用是初始化。通過self引用的實力對象為每一個實例添加屬性楷力。因為self 引用了調(diào)用方法的實例對象喊式,由此可以得出_init(self) 方法的執(zhí)行是在創(chuàng)建對象之后孵户。
class People:
def __init__(self):
self.name = "DragonFang"
self.age = 18
def show(self):
print("name:%s ,age:%d " % (self.name, self.age))
dragon_fang = People()
dragon_fang.show()
xiao_ming = People()
xiao_ming.show()
# 結(jié)果為:
# name:DragonFang ,age:18
# name:DragonFang ,age:18
怎么讓每個實例對象的名字不相同呢?傳參垃帅,通過給_init_(self)傳參初始化每個實例對象的name延届、age剪勿。
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print("name:%s ,age:%d " % (self.name, self.age))
dragon_fang = People("DragonFang", 19)
dragon_fang.show()
xiao_ming = People("xiaoMing", 20)
xiao_ming.show()
# 結(jié)果為:
# name:DragonFang ,age:19
# name:xiaoMing ,age:20
魔法方法_Str_(self)
魔法方法_Str_(self) 的作用是打印對象的描述信息贸诚,必須有返回值,且返回值必須是字符串厕吉。(附官方說明:Called by str(object) and the built-in functions format() and print() to compute the “informal” or nicely printable string representation of an object. The return value must be a string object.)
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def show(self):
print("name:%s ,age:%d " % (self.name, self.age))
def __str__(self):
return "name:%s ,age:%d " % (self.name, self.age)
dragon_fang = People("DragonFang", 19)
dragon_fang.show()
print(dragon_fang)
# 結(jié)果為:
# name:DragonFang ,age:19
# name:DragonFang ,age:19
需要注意 _str(self) 必須有返回值酱固,而且返回值的類型必須是字符串類型,否則報錯头朱。
所以 _str(self) 的作用一般是用來打印對象的描述信息运悲。
魔法方法_del_(self)
魔法方法_del_(self) 當(dāng)對象即將被銷毀的時候執(zhí)行。(附官方說明:Called when the instance is about to be destroyed)
什么情況下對象會被銷毀项钮?
- 程序結(jié)束
- 對象的所有引用被刪除
_del_(self) 方法的作用班眯,
- 因為del(self) 方法在對象即將被銷毀時調(diào)用,所以可以驗證對象是否被銷毀烁巫。
- 因為del(self) 方法在對象即將被銷毀時調(diào)用署隘,所以也可以做一些其他操作,比如釋放資源亚隙。
數(shù)據(jù)的保護
使用對象.屬性可以在類的外部修改屬性的值磁餐,但是這種修改方式不安全。
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "name:%s ,age:%d " % (self.name, self.age)
dragon_fang = People("DragonFang", 19)
dragon_fang.age = -500
print(dragon_fang)
# 結(jié)果為:
# name:DragonFang ,age:-500 # 這是傳說中的向天再借五百年嗎阿弃?
怎樣確保數(shù)據(jù)的正確性呢诊霹?方法,通過方法設(shè)置可以確保數(shù)據(jù)的正確性渣淳。
class People:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "name:%s ,age:%d " % (self.name, self.age)
def set_age(self, new_age):
if new_age >= 0:
self.age = new_age
print("數(shù)據(jù)不合法")
dragon_fang = People("DragonFang", 19)
dragon_fang.set_age(-500)
print(dragon_fang)
# 結(jié)果為:
# 數(shù)據(jù)不合法
# name:DragonFang ,age:19
你可能會雖然通過方法確保了正確脾还,但是依然可以通過對象.屬性的方式設(shè)置屬性的值,該怎么解決呢入愧?私有荠呐,使用私有屬性,私有屬性配合方法使用能更好的保護數(shù)據(jù)的正確性砂客。通過在屬性前加兩條下劃線“_”的形式將公有屬性變成私有屬性
class People:
def __init__(self, name, age):
self.name = name
self.__age = age
def __str__(self):
return "name:%s ,age:%d " % (self.name, self.__age)
def set_age(self, new_age):
if new_age >= 0:
self.__age = new_age
print("數(shù)據(jù)不合法")
dragon_fang = People("DragonFang", 19)
dragon_fang.set_age(-500)
print(dragon_fang)
dragon_fang.__age
Traceback (most recent call last):
File "E:/workspace/pycharm/pycharm/Demo.py", line 18, in <module>
dragon_fang.__age
AttributeError: 'People' object has no attribute '__age'
數(shù)據(jù)不合法
name:DragonFang ,age:19
報錯了泥张,說明在類外不能使用對象.屬性名的方式訪問私有屬性。
不能訪問私有屬性鞠值,能不能訪問私有方法媚创?私有方法同樣是通過增加兩條下劃線“_”的形式
class People:
def __init__(self, name, age):
self.name = name
self.__age = age
def __show(self):
print("name:%s ,age:%d " % (self.name, self.__age))
dragon_fang = People("DragonFang", 19)
dragon_fang.__show()
Traceback (most recent call last):
File "E:/workspace/pycharm/pycharm/Demo.py", line 11, in <module>
dragon_fang.__show()
AttributeError: 'People' object has no attribute '__show'
報錯,說明不能再類外通過對象.方法名() 的方式訪問私有方法
偽私有
偽彤恶,假的钞钙。偽私有鳄橘,不是真正的私有。python中沒有真正意義上的私有都是偽私有芒炼。
為什么這么說瘫怜?
class People:
def __init__(self, name, age):
self.name = name
self.__age = age
def __show(self):
print("name:%s ,age:%d " % (self.name, self.__age))
dragon_fang = People("DragonFang", 19)
dragon_fang._People__show()
# 結(jié)果為:
# name:DragonFang ,age:19
私有只是解釋器在處理私有屬性,私有方法的時候改變了屬性 或者方法的名字本刽,從而達到私有的目的鲸湃。僅供了解,僅供了解子寓,僅供了解暗挑。強烈不建議使用,強烈不建議使用斜友,強烈不建議使用炸裆。
到此結(jié) ? DragonFangQy ? 2018.4.10