Python入門課程系列:
- Python學(xué)習(xí) day1:認(rèn)識(shí)Python
- Python學(xué)習(xí) day2:判斷語句與循環(huán)控制
- Python學(xué)習(xí) day3:高級(jí)數(shù)據(jù)類型
- Python學(xué)習(xí) day4:函數(shù)基礎(chǔ)
- Python學(xué)習(xí) day5:函數(shù)
- Python學(xué)習(xí) day6:內(nèi)置函數(shù)
目標(biāo):
- 通過明確面向?qū)ο笳Z言的基本特征,在頭腦中形成基本的面向?qū)ο蟮母拍睿ㄖ攸c(diǎn)枣购、難點(diǎn))
- 通過定義類和對(duì)象午阵,對(duì)事物進(jìn)行抽象化(重點(diǎn))
- 適應(yīng) _ init _ 方法,self屬性快速初始化屬性(重點(diǎn)段标、難點(diǎn))
- 使用魔法方法輕松增加類的功能(重點(diǎn))
1. 面對(duì)對(duì)象介紹
概述
- 面向過程:就是我們一開始學(xué)習(xí)的,按照解決問題的步驟去寫代碼 [根據(jù)業(yè)務(wù)邏輯從上到下寫代碼]。
- 函數(shù)式:將某功能代碼封裝到函數(shù)中料仗,日后便無需重復(fù)編寫状婶,僅調(diào)用函數(shù)即可意敛。
- 面向?qū)ο缶幊蹋簅op [object oriented programming],是一種解決軟件復(fù)用的設(shè)計(jì)和編程方法膛虫。這種方法把軟件系統(tǒng)中相近相似的操作邏輯和操作草姻、應(yīng)用數(shù)據(jù)、狀態(tài)等以類的形式描述出來稍刀,以對(duì)象實(shí)例的形式在軟件系統(tǒng)中復(fù)用撩独,以達(dá)到提高軟件開發(fā)效率的作用。(將數(shù)據(jù)與函數(shù)綁到一起账月,進(jìn)行封裝综膀,這樣能夠更快速的開發(fā)程序,減少了重復(fù)代碼的重寫過程)
面向過程和面向?qū)ο蠖际且环N解決實(shí)際問題的思路担平。
面向過程關(guān)注的是:怎么做
面向?qū)ο箨P(guān)注的是:誰來做
從計(jì)算機(jī)的角度來看:面向過程不適合做大項(xiàng)目,面向?qū)ο筮m合更大的項(xiàng)目設(shè)計(jì)锭部。
2. 類和對(duì)象的概念
類和對(duì)象都是oop中重要的概念
- 類:是具有一組相同或相似特征【屬性】和行為【方法】的一系列對(duì)象的集合(就是一個(gè)模版暂论,模版里可以包含多個(gè)函數(shù),函數(shù)里實(shí)現(xiàn)一些功能)
- 對(duì)象:是實(shí)實(shí)在在的一個(gè)東西拌禾,是根據(jù)模版創(chuàng)建的實(shí)例(類的實(shí)例化取胎、具象化),通過實(shí)例對(duì)象可以執(zhí)行類中的函數(shù)
類是對(duì)象的抽象化湃窍,而對(duì)象是類的一個(gè)實(shí)例
類是不在內(nèi)存中開辟任何空間的闻蛀,只有當(dāng)類被創(chuàng)建對(duì)象時(shí),才會(huì)給對(duì)象一個(gè)空間
類的組成部分:類(Class)由3個(gè)部分構(gòu)成
- 類的名稱:類名
- 類的屬性:一組數(shù)據(jù)(特征)
- 類的方法:允許對(duì)象進(jìn)行操作的方法(行為)
例如創(chuàng)建一個(gè)人類:事物名稱(類名):人(Person)觉痛;屬性:身高(height)、年齡(age)茵休;方法:吃(eat)薪棒、跑(run)...
類的抽象:具有相同(或者類似)屬性和行為的一系列對(duì)象的集合都可以抽象出一個(gè)類
例如:抽象坦克大戰(zhàn)中的類
坦克:類名:坦克手蝎; 屬性:類型、血量俐芯; 方法:發(fā)射子彈
墻:類名:Wall棵介; 屬性:類型、血量吧史; 方法:阻擋
子彈:類名:Wall邮辽; 屬性:殺傷力
3. 定義類和對(duì)象
# 格式:
# class 類名(object): #object可以省略
# 屬性
# 方法
class Person:
'''
對(duì)應(yīng)人的特征
'''
name='小花' #‘name’是類屬性
age=5
'''
對(duì)應(yīng)人的行為
'''
def eat(self): #‘eat’是類的實(shí)例方法
print('乖乖吃飯')
pass
def run(self):
print('飛快的跑')
pass
coco=Person() #創(chuàng)建一個(gè)對(duì)象
coco.eat() #調(diào)用函數(shù)
#乖乖吃飯
print('{}的年齡是:{}'.format(coco.name,coco.age))
#小花的年齡是:5
4. 實(shí)例方法與屬性
實(shí)例方法:在類的內(nèi)部,使用def關(guān)鍵字來定義贸营,第一個(gè)參數(shù)默認(rèn)是self的方法(可以是其他的名字如parms吨述,但是這個(gè)位置必須被占用,且為第一個(gè)參數(shù))莽使。
實(shí)例方法歸屬于類的實(shí)例所有锐极,所有的實(shí)例都可以去調(diào)用。
??Python的函數(shù)(Method)與方法(Function)
1. 函數(shù)(function)是Python中一個(gè)可調(diào)用對(duì)象(callable), 方法(method)是一種特殊的函數(shù)芳肌。
2. 一個(gè)可調(diào)用對(duì)象是方法和函數(shù),和這個(gè)對(duì)象無關(guān)肋层,僅和這個(gè)對(duì)象是否與類或?qū)嵗壎ㄓ嘘P(guān)(bound method)亿笤。
3. 實(shí)例方法,在類中未和類綁定栋猖,是函數(shù)净薛;在實(shí)例中,此實(shí)例方法與實(shí)例綁定蒲拉,即變成方法肃拜。
4. 靜態(tài)方法沒有和任何類或?qū)嵗壎ǎ造o態(tài)方法是個(gè)函數(shù)雌团。
5. 裝飾器不會(huì)改變被裝飾函數(shù)或方法的類型燃领。
6. 類實(shí)現(xiàn)call方法,其實(shí)例也不會(huì)變成方法或函數(shù),依舊是類的實(shí)例。
7. 使用callalble() 只能判斷對(duì)象是否可調(diào)用,不能判斷是不是函數(shù)或方法锦援。
8. 判斷對(duì)象是函數(shù)或方法應(yīng)該使用type(obj)猛蔽。
屬性:類里面定義的變量。定義在類里面略板,方法外面的屬性稱之為類屬性毁枯,定義在方法里面使用self引用的屬性稱之為實(shí)例屬性。(在定義的時(shí)候叮称,不管是類屬性還是實(shí)例屬性种玛,最好不要重復(fù))
一些共有的屬性會(huì)被寫進(jìn)類屬性藐鹤,而同一類下的不同對(duì)象的不同屬性會(huì)被寫進(jìn)實(shí)例屬性
類屬性可以用類和實(shí)例訪問,實(shí)例屬性只能用實(shí)例訪問不能用類訪問
實(shí)例屬性每個(gè)實(shí)例各自擁有蒂誉,相互獨(dú)立教藻;而類屬性有且只有1份,創(chuàng)建的實(shí)例都會(huì)繼承自唯一的類屬性右锨。意思就是綁定在一個(gè)實(shí)例上的屬性不會(huì)影響到其它的實(shí)例括堤。如果在類上綁定一個(gè)屬性,那么所有的實(shí)例都可以訪問類屬性绍移,且訪問的類屬性是同一個(gè)悄窃,一旦類屬性改變就會(huì)影響到所有的實(shí)例。
5. _ init _方法
_ init _(self)方法蹂窖,初始化方法轧抗,實(shí)例化對(duì)象的時(shí)候自動(dòng)調(diào)用,完成一些初始化設(shè)置瞬测,如賦值或添加屬性横媚。在創(chuàng)建新對(duì)象的時(shí)候,是自動(dòng)執(zhí)行的月趟。
class Person():
def __init__(self):
'''
實(shí)例屬性的聲明
'''
self.name='小花'
self.age=5
self.gender='female'
def eat(self):
'''
吃的行為
:return:
'''
print('乖乖吃飯')
pass
flower=Person()
print(flower.name)
#小花
_ init _ 傳參
如果_ init _方法里面的屬性固定了灯蝴,每個(gè)類創(chuàng)建出來的對(duì)象屬性都一樣,這個(gè)時(shí)候可以考慮將屬性當(dāng)參數(shù)在實(shí)例化對(duì)象的時(shí)候傳進(jìn)去孝宗,讓類更通用
class Person:
def __init__(self,name,age,gender):
'''
實(shí)例屬性的聲明
'''
self.name=name
self.age=age
self.gender=gender
def eat(self,food):
print(self.name+'喜歡'+food)
pass
maomao=Person('毛毛','26','female')
maomao.eat('麻辣燙')
print(maomao.name)
#毛毛喜歡麻辣燙
#毛毛
xiaogeng=Person('耿耿','22','female')
print(xiaogeng.age)
xiaogeng.eat('奶茶')
#耿耿喜歡奶茶
#22
類屬性和_ init _()定義屬性的區(qū)別:
類屬性相當(dāng)于是公有的穷躁,當(dāng)修改類屬性的值,隨后創(chuàng)建的對(duì)象屬性都會(huì)改變因妇。而通過 _ init _ ()定義屬性的值问潭,在對(duì)屬性值進(jìn)行修改后,只會(huì)對(duì)這一個(gè)對(duì)象生效婚被。
總結(jié)_ init _():
- python自帶的內(nèi)置函數(shù)狡忙,具有特殊的含義,特點(diǎn)是用雙下劃線包起來的摔寨,是一種魔術(shù)方法
- 是一個(gè)初始化的方法去枷,用來定義實(shí)例屬性和初始化數(shù)據(jù)的,在創(chuàng)建對(duì)象的時(shí)候自動(dòng)調(diào)用是复,不需要手動(dòng)調(diào)用
- 利用傳參的機(jī)制可以讓我們定義功能更加強(qiáng)大并且方便使用的類
6. 理解self
self和對(duì)象指向同一個(gè)內(nèi)存地址删顶,可以認(rèn)為self就是對(duì)象的引用
class Car(object):
def getself(self):
print('self=%s'%(id(self)))
bmw=Car()
print(id(bmw))
#140395478957360
bmw.getself()
#self=140395478957360
self傳參問題:
所謂的self,可以理解為對(duì)象自己淑廊,某個(gè)對(duì)象調(diào)用其方法時(shí)逗余,python解釋器會(huì)把這個(gè)對(duì)象作為第一個(gè)參數(shù)傳遞給self,所以開發(fā)者只需要傳遞后面的參數(shù)即可季惩。
class Car(object):
def __init__(self,name,color):
self.name=name
self.color=color
#創(chuàng)建一個(gè)方法打印self的id
def getself(self):
print('self=%s'%(id(self)))
bmw=Car('寶馬','黑色')
print(id(bmw))
bmw.getself()
#140687813664720
#self=140687813664720
小結(jié):
self只有在類中定義實(shí)例方法的時(shí)候才有意義录粱,在調(diào)用的時(shí)候不必傳入相應(yīng)的參數(shù)腻格,而是由解釋器自動(dòng)去指向
self的名字是可以更改的,可以定義成其他的名字啥繁,只是約定俗的成定義成了self
self指的是實(shí)例對(duì)象本身菜职,相當(dāng)于java中的this
7.魔法方法
在python中,有一些內(nèi)置好的特定方法旗闽,方法名是“_ xxx _“酬核,在進(jìn)行特定操作時(shí)會(huì)被調(diào)用,這些方法稱之為魔法方法
常見的魔法方法:
_ init _方法
:初始化一個(gè)類适室,在創(chuàng)建實(shí)例對(duì)象為其賦值時(shí)使用嫡意。_ str _方法
:在將對(duì)象轉(zhuǎn)換成字符串str(對(duì)象)測(cè)試的時(shí)候,打印對(duì)象的信息捣辆。(是自定義格式輸出的蔬螟,必須有返回值。)_ new _方法
:創(chuàng)建并返回一個(gè)實(shí)例對(duì)象汽畴,調(diào)用了一次旧巾,就會(huì)得到一個(gè)對(duì)象。_ class _方法
:獲得已知對(duì)象的類(對(duì)象. _class _)忍些。_ del _方法
:對(duì)象在程序運(yùn)行結(jié)束后進(jìn)行對(duì)象銷毀的時(shí)候調(diào)用這個(gè)方法菠齿,來釋放資源。_ mro _ 方法
:python的類具有多繼承特性坐昙,如果繼承關(guān)系太復(fù)雜,很難看出會(huì)先調(diào)用哪個(gè)屬性或方法芋忿。為了方便且快速地看清繼承關(guān)系和順序炸客,可以用 _ mro _ 方法來獲取這個(gè)類的調(diào)用順序。_ slots _ 方法
:python可以動(dòng)態(tài)添加屬性戈钢。如果要限制在運(yùn)行的時(shí)候給類添加屬性痹仙,可以在定義class的時(shí)候,定義一個(gè)特殊的 _ slots _ 變量殉了,來限制該class實(shí)例能添加的屬性开仰。只有在 _ slots _ 變量中的屬性才可以被添加,沒有在 _ slots _ 變量中的屬性會(huì)添加失敗薪铜。
#1. _ init _方法
class Animal(object): #創(chuàng)建一個(gè)初始化方法
def __init__(self,name,color):
self.name=name
self.color=color
dog=Animal('旺財(cái)','白色') #實(shí)例化對(duì)象
print(dog) #直接打印對(duì)象众弓,輸出的只是一串 類似id地址的信息
#<__main__.Animal object at 0x7fbd93970d30>
#2. _ str _方法
class Animal(object): #創(chuàng)建一個(gè)初始化方法
def __init__(self,name,color):
self.name=name
self.color=color
def __str__(self):
return '我的名字是%s,我的顏色是%s'%(self.name,self.color)
dog=Animal('旺財(cái)','白色') #實(shí)例化對(duì)象
print(dog)
#我的名字時(shí)旺財(cái)隔箍,我的顏色時(shí)白色
#3. _ new _方法 #用來做對(duì)象實(shí)例化
#我們不在類里面定義new函數(shù)谓娃,這個(gè)函數(shù)就會(huì)按照系統(tǒng)默認(rèn)的內(nèi)容運(yùn)行。默認(rèn)的new函數(shù)可以創(chuàng)造對(duì)象蜒滩,但我們自己寫了new以后滨达,就優(yōu)先運(yùn)行我們自己的new奶稠,而不是系統(tǒng)的new。
class Animal(object): #創(chuàng)建一個(gè)初始化方法
def __init__(self,name,color):
self.name=name
self.color=color
print('----init----函數(shù)執(zhí)行')
def __str__(self):
return '我的名字是%s捡遍,我的顏色是%s'%(self.name,self.color)
pass
def __new__(cls, *args, **kwargs):
'''
創(chuàng)建對(duì)象實(shí)例的方法 每調(diào)用一次 就會(huì)生成一個(gè)新的對(duì)象 cls就是class的縮寫
場(chǎng)景:可以控制創(chuàng)建對(duì)象的一些屬性限定 經(jīng)常在做單例模式的時(shí)候使用
:param args:
:param kwargs:
'''
print('----new----函數(shù)執(zhí)行')
return object.__new__(cls) #cls代表當(dāng)前這個(gè)類 在這里是真正創(chuàng)建對(duì)象實(shí)例的
pass
dog=Animal('旺財(cái)','白色')
print(dog) #實(shí)例化對(duì)象
# ----new----函數(shù)執(zhí)行 #new是最先執(zhí)行的
# ----init----函數(shù)執(zhí)行
# 我的名字是旺財(cái)锌订,我的顏色是白色
class Animal(object): #創(chuàng)建一個(gè)初始化方法
def __init__(self,name,color):
self.name=name
self.color=color
print('----init----函數(shù)執(zhí)行')
def __str__(self):
return '我的名字是%s,我的顏色是%s'%(self.name,self.color)
pass
def __new__(cls, *args, **kwargs):
print('----new----函數(shù)執(zhí)行') #這個(gè)new雖然運(yùn)行了画株,但是沒有像上面那樣構(gòu)建對(duì)象實(shí)例辆飘,所以 就返不回對(duì)象,只能返回None
pass
dog=Animal('旺財(cái)','白色')
print(dog)
# ----new----函數(shù)執(zhí)行
# None
??_ new _ 和 _ init _函數(shù)的區(qū)別 :
- _ new _ 類的實(shí)例化方法必須要返回該實(shí)例污秆,否則對(duì)象就創(chuàng)建不成功
- _ init _ 用來做數(shù)據(jù)屬性的初始化工作劈猪,也可以認(rèn)為是實(shí)例的構(gòu)造方式,接受類的實(shí)例 self 并對(duì)其進(jìn)行構(gòu)造
- _ new _ 至少有一個(gè)參數(shù)是cls良拼,代表要實(shí)例化的類战得,此參數(shù)在實(shí)例化時(shí)由python解釋器自動(dòng)提供
8. 案例-決戰(zhàn)紫禁之巔
問題分析:
決戰(zhàn)紫禁之巔有2個(gè)人物:西門吹雪和葉孤城
- 屬性
name:玩家的名字
blood:玩家血量 - 方法
tong()捅對(duì)象一刀,對(duì)象掉血10滴
karen()砍對(duì)象一刀庸推,對(duì)象掉血15滴
chino()吃一顆藥常侦,補(bǔ)血10滴
_ str _ 打印玩家狀態(tài)
# 實(shí)現(xiàn)步驟
# 1. 定義類[角色類],創(chuàng)建 _init_ 方法
import time #導(dǎo)入時(shí)間的包(函數(shù)庫)
class Role:
def __init__(self, name, hp):
'''
構(gòu)造初始化函數(shù)
:param name:角色名
:param hp:血量
'''
self.name = name
self.hp = hp
pass
def tong(self, enemy):
'''
捅一刀(創(chuàng)建玩家技能的方法)
:param enemy: 敵人
:return:
'''
enemy.hp -= 10 # 敵人減掉10滴血
info = '【%s】捅了【%s】一刀' %(self.name, enemy.name)
print(info)
pass
def kanren(self, enemy):
'''
砍人
:param enemy:敵人
:return:
'''
enemy.hp -= 15 # 敵人減掉15滴血
info = '【%s】捅了【%s】一刀' %(self.name, enemy.name)
print(info)
pass
def chiyao(self):
'''
吃藥
:return:
'''
self.hp += 10
info = '【%s】吃了一顆補(bǔ)血藥贬媒,增加了10滴血' %(self.name)
print(info)
pass
def __str__(self):
return '%s 還剩下 %s的血量'%(self.name,self.hp)
# 1. 創(chuàng)建2個(gè)實(shí)例化對(duì)象【西門吹雪】和【葉孤城】
xmcx=Role('西門吹雪',100)
ygc=Role('葉孤城',100)
while True:
if xmcx.hp<=0 or ygc.hp<=0:
break
xmcx.tong(ygc) #西門吹雪捅葉孤城
print(ygc) #打印對(duì)象狀態(tài)
print(xmcx)
print('******************************')
ygc.tong(xmcx)
print(ygc) #打印對(duì)象狀態(tài)
print(xmcx)
print('******************************')
xmcx.chiyao()
print(ygc) #打印對(duì)象狀態(tài)
print(xmcx)
time.sleep(1) #休眠暫停一秒鐘
pass
print('對(duì)戰(zhàn)結(jié)束')
小結(jié)
1. 類和對(duì)象的概念
類就是一個(gè)模版聋亡,模版里可以包含多個(gè)函數(shù),函數(shù)里實(shí)現(xiàn)一些功能 际乘;
對(duì)象則是根據(jù)模版創(chuàng)建的實(shí)例坡倔,通過實(shí)例對(duì)象可以執(zhí)行類中的函數(shù)。
2. 定義類和對(duì)象
使用class語句來創(chuàng)建一個(gè)新類脖含,class之后為類的名稱并以冒號(hào)結(jié)尾罪塔;
實(shí)例化類其他編程語言中一般使用關(guān)鍵字new,但是在Python中并沒有這個(gè)關(guān)鍵字养葵,類的實(shí)例化類似函數(shù)的調(diào)用方法征堪。
3. 實(shí)例方法與屬性
實(shí)例方法:在類的內(nèi)部,使用def關(guān)鍵字來定義关拒,第一個(gè)參數(shù)默認(rèn)是self的方法佃蚜;
定義在類的里面,方法外面的屬性稱之為類屬性着绊,定義在方法里面使用self引用的屬性稱之為實(shí)例屬性谐算。
4. _ init _ 方法
構(gòu)造初始化函數(shù),在創(chuàng)建實(shí)例對(duì)象為其賦值時(shí)使用畔柔。
5. 理解self
self和對(duì)象指向同一個(gè)內(nèi)存地址氯夷,self就是對(duì)象的引用。
6. 魔法方法
在python中靶擦,有一些內(nèi)置好的特定的方法腮考;
方法名是“ _ xxx _ ”雇毫;
在進(jìn)行特定的操作時(shí)會(huì)自動(dòng)被調(diào)用(一般不會(huì)手動(dòng)去調(diào)用)。
課后作業(yè)·問答題
- 什么是類踩蔚,什么是對(duì)象
- python中定義一個(gè)類的語法格式是什么
- 類(class)由哪三個(gè)部分構(gòu)成
- _ init _ 方法有什么作用棚放,如何定義
- 方法中的“self”代表什么
- 在類中定義init方法的時(shí)候第一個(gè)形參必須是self嗎?self可以用其他東西代替嗎馅闽?
- Python面向?qū)ο笾械哪Хǚ椒ㄊ侨绾味x的飘蚯,魔法方法需要開發(fā)人員去調(diào)用嗎?
- _ str _ 方法可以沒有返回值福也,這句話是否正確局骤?
- 查看下面代碼,請(qǐng)寫出有哪些是屬性暴凑,哪些是實(shí)例方法叫挟。
class Person(object):
foot=2
eye=2
mouth=1
def __init__(self,name,age):
self.name=name
self.age=age
print('self=%s'%id(self))
def run(self):
print('慢慢跑')
def eat(self):
print('乖乖吃')
hua=Person('小花',5)
print('hua=%s'%id(hua))
課后作業(yè)·實(shí)操題
- python中如何通過類創(chuàng)建對(duì)象赔嚎,請(qǐng)用代碼舉例說明瘩将。
- 如何在類中定義一個(gè)方法锐涯,請(qǐng)用代碼舉例說明。
- 定義一個(gè)水果類嗦篱,然后通過水果類冰单,創(chuàng)建蘋果對(duì)象、橘子對(duì)象灸促、西瓜對(duì)象并分別添上顏色屬性诫欠。
- 請(qǐng)編寫代碼,驗(yàn)證self就是實(shí)例本身浴栽。
- 定義一個(gè)Animal類
(1)使用 _ init _ 初始化方法為對(duì)象添加初始屬性呕诉。如顏色、名字吃度、年齡。
(2)定義動(dòng)物方法贴硫,如run椿每、eat等方法。如調(diào)用eat方法時(shí)打印xx在吃東西即可英遭。
(3)定義一個(gè) _ str _ 方法间护,輸出對(duì)象的所有屬性。 - 請(qǐng)將決戰(zhàn)紫禁之巔重寫一遍挖诸,并理解每個(gè)方法的使用