python面向对象生动讲解_Python面向对象语法精讲
本專題的內(nèi)容結(jié)構(gòu):
第一部分主要是:面向?qū)ο蠡A(chǔ)
第二部分主要是:面向?qū)ο筮M(jìn)階
第一部分的結(jié)構(gòu):
unit1:面向?qū)ο缶幊棠J?#xff1a;
(1),面向?qū)ο缶幊趟枷?/p>
(2),面向?qū)ο蟮娜齻€(gè)特征
(3),Python面向?qū)ο笮g(shù)語(yǔ)
unit2:Python類的構(gòu)建:
(1),類的基本構(gòu)建
(2),類的屬性和方法
(3),類的構(gòu)造函數(shù)和析構(gòu)函數(shù)
unit3:實(shí)例1:銀行ATM等待時(shí)間分析
(1),對(duì)象的設(shè)計(jì)和構(gòu)建
(2),生活現(xiàn)象的程序分析
unit4:Python類的封裝
(1),私有屬性和公開(kāi)屬性
(2),私有方法和公開(kāi)方法
(3),保留屬性和保留方法
unit5:Python類的繼承:
(1),子類,父類與超類
(2),類的方法重載和屬性重載
(3),類的多繼承
第二部分的結(jié)構(gòu):
unit1:Python類的運(yùn)算:
(1),運(yùn)算符的理解
(2),各類運(yùn)算符的重載
unit2:Python類的多態(tài):
(1),多態(tài)的理解
(2),參數(shù)類型的多態(tài)
(3),參數(shù)形式的多態(tài)
unit3:實(shí)例2:圖像的四則運(yùn)算
(1),PIL庫(kù)和Numpy 庫(kù)實(shí)踐
(2),圖像的加減乘除操作
unit4:Python對(duì)象的引用
(1),引用的理解
(2),淺拷貝和深拷貝
unit5:Python類的高級(jí)話題:
(1),類的特殊裝飾器
(2),命名空間的理解
(3),類的名稱修飾
第一部分的內(nèi)容:
unit1:面向?qū)ο缶幊棠J?#xff1a;
(1),萬(wàn)物皆對(duì)象:
自然意義上的對(duì)象:獨(dú)立的存在 或 作為目標(biāo)的事物
>獨(dú)立性:對(duì)象都存在清晰的邊界,重點(diǎn)在于劃分邊界
>功能性:對(duì)象都能表現(xiàn)出一些功能,操作或行為
>交互性:對(duì)象之間存在交互,如:運(yùn)算和繼承
Python語(yǔ)言的“萬(wàn)物皆對(duì)象”:
>Python語(yǔ)言中所有數(shù)據(jù)類型都是對(duì)象,函數(shù)是對(duì)象,模塊是對(duì)象
>Python所有類都是繼承于最基礎(chǔ)類object
>Python語(yǔ)言中數(shù)據(jù)類型的操作功能都是類方法的體現(xiàn)
(2),面向?qū)ο缶幊趟枷?#xff1a;
OOP :Object-Oriented Programming
>OOP :面向?qū)ο缶幊?#xff0c;一種編程思想,重點(diǎn)在于高抽象的 復(fù)用代碼
>OOP 把對(duì)象當(dāng)做程序的基本單元,對(duì)象包含數(shù)據(jù)和操作數(shù)據(jù)的函數(shù)
>OOP 本質(zhì)是把問(wèn)題解決抽象為以對(duì)象為中心的計(jì)算機(jī)程序
注:
>OOP在較大規(guī)模或復(fù)雜項(xiàng)目中十分有用,OOP可以提高協(xié)作產(chǎn)量
>OOP最主要的價(jià)值在于代碼復(fù)用
>OOP只是一種編程方式,并非解決問(wèn)題的高級(jí)方法
面向過(guò)程 vs 面向?qū)ο?/p>
>面向過(guò)程:以解決問(wèn)題的過(guò)程步驟為核心編寫程序的方式
>面向?qū)ο?#xff1a;以問(wèn)題對(duì)象構(gòu)建和應(yīng)用為核心編寫程序的方式
>所有OOP能解決的問(wèn)題,面向過(guò)程都能解決
小例子:
(3),面向?qū)ο蟮娜齻€(gè)特征:
OOP的三個(gè)特征:
>封裝:屬性和方法的抽象,用數(shù)據(jù)和操作數(shù)據(jù)的方法來(lái)形成對(duì)象邏輯
>繼承:代碼復(fù)用的高級(jí)抽象,用對(duì)象之間的繼承關(guān)系來(lái)形成代碼復(fù)用
>多態(tài):方法靈活性的抽象,讓對(duì)象的操作更加靈活,更多復(fù)用代碼
它能讓更少的對(duì)象名稱來(lái)支持更多的對(duì)象操作
它們都是表達(dá)了代碼抽象和代碼復(fù)用,
封裝的理解:
封裝Encapsulation:屬性和方法的抽象
>屬性的抽象:對(duì)類的屬性(變量)進(jìn)行定義,隔離及保護(hù)
>方法的抽象:對(duì)類的方法(函數(shù))進(jìn)行定義,隔離及保護(hù)
>目標(biāo)是形成一個(gè)類/對(duì)象 對(duì)外可操作屬性和方法的接口
繼承的理解:
繼承 Inheritance:代碼復(fù)用的高級(jí)抽象
>繼承是面向?qū)ο蟪绦蛟O(shè)計(jì)精髓之一
>實(shí)現(xiàn)了以類為單位的高抽象級(jí)別代碼復(fù)用
>繼承是新定義的類 能夠幾乎完全使用原有類屬性和方法的過(guò)程
多態(tài)的理解:
多態(tài) Polymorphism :僅針對(duì)方法,方法靈活性的抽象
>參數(shù)類型的多態(tài):一個(gè)方法能夠處理多個(gè)類型的能力
>參數(shù)形式的多態(tài):一個(gè)方法能夠接受多個(gè)參數(shù)的能力
>多態(tài)是 OOP的一個(gè)傳統(tǒng)概念,Python天然支持多態(tài),不需要特殊語(yǔ)法
其他語(yǔ)言中要用特定的語(yǔ)法用多態(tài),但是Python中設(shè)計(jì)的弱類型天然支持多態(tài)
對(duì)多態(tài)的理解重點(diǎn)是概念和思路上的理解,更能理解Python對(duì)類的方法靈活性的抽象是如何表達(dá)的,
(4),Python面向?qū)ο笮g(shù)語(yǔ):
先簡(jiǎn)要過(guò)一遍,后會(huì)介紹:
類 Class 和 對(duì)象 Object :
>類:邏輯抽象和產(chǎn)生對(duì)象的模板,一組變量和函數(shù)的特定編排
>對(duì)象:具體表達(dá)數(shù)據(jù)及操作的實(shí)體,相當(dāng)于程序中的"變量"
>實(shí)例化:從類到對(duì)象的過(guò)程,所有"對(duì)象"都源于某個(gè)"類"
對(duì)象: 對(duì)象具體分為: 類對(duì)象和實(shí)例對(duì)象
類對(duì)象 vs 實(shí)例對(duì)象 :
>類對(duì)象:Class Object,當(dāng)一個(gè)類建立之后,系統(tǒng)會(huì)維護(hù)個(gè)Python類基本信息的數(shù)據(jù)結(jié)構(gòu)
>實(shí)例對(duì)象:Instance Object,Python類實(shí)例后產(chǎn)生的對(duì)象,簡(jiǎn)稱:對(duì)象
>這是一組概念,類對(duì)象全局只有一個(gè)(保存類的基本信息),實(shí)例對(duì)象可以生成多個(gè)
屬性: 存儲(chǔ)數(shù)據(jù)的“變量”,分為 :類屬性 和實(shí)例屬性
方法: 操作數(shù)據(jù)的"函數(shù)",
包括:類方法,實(shí)例方法,自由方法,靜態(tài)方法,保留方法
三個(gè)特性:封裝繼承多態(tài)
繼承:基類,派生類,子類,父類,超類,重載
命名空間:程序元素作用域的表達(dá)
構(gòu)造和析構(gòu):生成對(duì)象和刪除對(duì)象的過(guò)程
(5),Python面向?qū)ο髮?shí)例入門:
是上面的那個(gè)例子,計(jì)算價(jià)格的和,
出現(xiàn)新的保留字class
它可以定義抽象的Product 類,
1 classProduct():2 def __init__(self,name):3 self.name =name4 self.label_price =05 self.real_price =06
7 c = Product("電腦")8 d = Product("打印機(jī)")9 e = Product("投影儀")10 c.label_price,c.real_price = 10000,8000
11 d.label_price,d.real_price = 2000,1000
12 e.label_price,e.real_price = 1500,900
13 s1 ,s2 =0,014 for i in[c,d,e]:15 s1+=i.label_price16 s2+=i.real_price17 print(s1,s2)
View Code
unit2:Python類的構(gòu)建:
python類的構(gòu)建需要關(guān)注的地方:
就是上面的那個(gè)圖:它包含了構(gòu)建一個(gè)類所要關(guān)注的方方面面:
(1),類的基本構(gòu)建:
使用class保留字定義類:
class <類名>:
[可以寫個(gè)類描述字符串"documentation string"]
<語(yǔ)句塊>
注:類定義不限位置,可以包含在分支或其他從屬語(yǔ)句塊中,執(zhí)行時(shí)存在即可
可以放在全局部分,也可以放在分支,函數(shù),等從屬語(yǔ)句塊中,由于Python語(yǔ)言是腳本語(yǔ)言,
所以在某個(gè)對(duì)象引用之前,只要是類被定義就可以。
類構(gòu)造之類的名字:可以是任意有效標(biāo)識(shí)符,建議采用大寫單詞的組合
如:ClassName ,BasicAuto ,BasicCreature
類構(gòu)造之類描述:在類的定義后首行,以獨(dú)立字符串形式定義
定義可以通過(guò)<類名>.__doc__屬性來(lái)訪問(wèn)
注:像這種前后都有兩個(gè)下劃線的屬性是Python給類保留的屬性,
class DemoClass:
"This is a demo for Python class"
pass
print(DemoClass.__doc__)
>>>This is a demo for Python class
介紹一個(gè)概念:類對(duì)象
大家不要把類和對(duì)象拆開(kāi),類對(duì)象是一個(gè)名詞,(Class Object)
>類定義完成后,默認(rèn)生成一個(gè)類對(duì)象
與其他語(yǔ)言不同,python的類只要定義完就會(huì)生成一個(gè)對(duì)象,但這個(gè)對(duì)象呢?只是與這個(gè)類唯一對(duì)應(yīng)的,
每一個(gè)類只唯一對(duì)應(yīng)一個(gè)類對(duì)象,這個(gè)類對(duì)象是存儲(chǔ)這個(gè)類的基本信息的
>每個(gè)類唯一對(duì)應(yīng)一個(gè)類對(duì)象,用于存儲(chǔ)這個(gè)類的基本信息
>類對(duì)象是type類的實(shí)例,表達(dá)為type類型
什么是type類型呢?
它是編譯器提供了一種類型,
class DemoClass:
"This is a demo for Python class"
print("hello DemoClass")
print(type(DemoClass))
輸出:
hello DemoClass
我們發(fā)現(xiàn),我們只是定義了這個(gè)類,但是它也執(zhí)行print("hello DemoClass)
這時(shí)因?yàn)樵趐ython中只要這個(gè)類被定義了, 就會(huì)生成一個(gè)表達(dá)它信息的 類對(duì)象
這個(gè)類對(duì)象是內(nèi)置包含在類的定義中的,
那么這個(gè)類對(duì)象的生成使得類定義中的一些語(yǔ)句被執(zhí)行,
因此,我們一般不在類的定義中直接包含語(yǔ)句,而是通過(guò)屬性和方法來(lái)增加操作功能
類對(duì)象并不是使用類的常用方式,
使用類的方式最常用的是:通過(guò)創(chuàng)建實(shí)例對(duì)象來(lái)使用類的功能
<對(duì)象名> = <類名>([<參數(shù)>])
進(jìn)一步采用<對(duì)象名>.<屬性名>和<對(duì)象名>.<方法名>()體現(xiàn)類的功能
實(shí)例對(duì)象的類型:
它所生成時(shí)的那個(gè)類的類型
class DemoClass:
"This is a demo for Python class"
pass
print(type(DemoClass))
cn = DemoClass()
print(type(cn))
輸出:
所以,實(shí)例對(duì)象和類對(duì)象是不一樣的 ,
實(shí)例對(duì)象是最常用的方式,
了解Python類的構(gòu)造函數(shù)
>類的構(gòu)造函數(shù)用于從類創(chuàng)建實(shí)例對(duì)象的過(guò)程
>類的構(gòu)造函數(shù)為實(shí)例對(duì)象創(chuàng)建提供了參數(shù)輸入方式
>類的構(gòu)造函數(shù)為實(shí)例屬性的定義和賦值提供了支持
了解Python類的屬性和方法:
>類的屬性:類中定義的變量,采用描述類的一些特性參數(shù)
>類的方法:類中定義且與類相關(guān)的函數(shù),用來(lái)給出類的操作功能
>屬性和方法是類對(duì)外交互所提供的兩種接口方式
(2),類的構(gòu)造函數(shù):
類的構(gòu)造函數(shù)是從類生成實(shí)例對(duì)象所使用的函數(shù),
Python中使用預(yù)定義的__init__()作為構(gòu)造函數(shù),
clsaa <類名>:
def __init__(self,<參數(shù)列表>)
<語(yǔ)句塊>
類實(shí)例化時(shí)所使用的函數(shù),可以接收參數(shù)并完成初始化操作
class DemoClass:
def __init__(self,name):
print(name)
dc1 = DemoClass("老王")
dc2 = DemoClass("老李")
輸出:
老王
老李
注:通過(guò)構(gòu)造函數(shù)__init__()可以為Python對(duì)象提供參數(shù)
還有,構(gòu)造函數(shù)默認(rèn)有個(gè)參數(shù)self ,它內(nèi)部使用的,默認(rèn)保留的,
__init__()的使用說(shuō)明:
>參數(shù):第一個(gè)參數(shù)約定是self,表示類實(shí)例自身,其他參數(shù)都是實(shí)例參數(shù)
>函數(shù)名:Python解釋器內(nèi)部定義的,由雙下劃線開(kāi)始和結(jié)束
>返回值:構(gòu)造函數(shù)沒(méi)有返回值,或返回None ,否則產(chǎn)生TypeError異常
self在類定義內(nèi)部代表類的實(shí)例
>self是Python面向?qū)ο笾屑s定的一個(gè)類參數(shù)
>self代表類的實(shí)例,在類內(nèi)部,self用于組合訪問(wèn)實(shí)例相關(guān)的屬性和方法
>相比較而言,類名代表類對(duì)象本身
(3),類的屬性:
屬性是類內(nèi)部定義的變量
>類屬性:類對(duì)象的屬性,由所有實(shí)例對(duì)象共享
>實(shí)例屬性:實(shí)例對(duì)象的屬性,由各實(shí)例所獨(dú)享
類的屬性和實(shí)例屬性是如何定義的?
我們知道屬性是變量,類中有兩個(gè)地方可以放變量,
第一個(gè)是在class的全局命名空間:
<類屬性名> =<類屬性初值>
第二個(gè)是在函數(shù)/方法中定義的它就是實(shí)例屬性:
class <類名>:
<類屬性名>=<類屬性初值>
def __init__(self,<參數(shù)列表>):
self.<實(shí)例屬性名> = <實(shí)例屬性初值>
...
class DemoClass:
count = 0 #直接在類中定義或賦值 無(wú)論在類內(nèi)類外,訪問(wèn)類屬性都要用<類名>.<屬性名>來(lái)訪問(wèn)
def __init__(self,name,age):
self.name = name
self.age = age
DemoClass.count +=1
dc1 = DemoClass("老王",45)
dc2 = DemoClass("老李",51)
print("總數(shù):",DemoClass.count)
print(dc1.name,dc2.name)
我們已經(jīng)知道,類屬性在類內(nèi),類外都是<類名>.<類屬性>
而對(duì)于實(shí)例屬性:
在類內(nèi)部,用self.<屬性名>訪問(wèn)
在類外部,用<對(duì)象名>.<屬性名>訪問(wèn)
注:在類外,類屬性也是可以用<對(duì)象名>.<屬性名>來(lái)訪問(wèn)的
class DemoClass:
def __init__(self,name):
self.name = name
#注:構(gòu)造函數(shù)沒(méi)有返回值
def luckey(self):
s = 0
for c in self.name:
s+=ord(c)%100
return s
dc1 = DemoClass("Wang")
dc2 = DemoClass("Li")
print(DemoClass.__dict__) #類對(duì)象的屬性字典
print(dc1.__dict__) #實(shí)例對(duì)象的屬性字典
print(dc2.__dict__) #實(shí)例對(duì)象的屬性字典
print(DemoClass.__dir__(DemoClass)) #類對(duì)象的屬性列表
print(dc1.__dir__()) #實(shí)例對(duì)象的屬性列表
(4),類的方法:
方法是類內(nèi)部定義的函數(shù):
>實(shí)例方法:實(shí)例對(duì)象的方法,由各實(shí)例對(duì)象獨(dú)享,最常用的形式
>類方法:類對(duì)象的方法,由所有實(shí)例對(duì)象共享
>自由方法:類中的一個(gè)普通函數(shù),由類所在命名空間管理,類對(duì)象獨(dú)享
>靜態(tài)方法:類中的一個(gè)普通函數(shù),由類對(duì)象和實(shí)例對(duì)象共享
>保留方法:由雙下劃線開(kāi)始和結(jié)束的方法,保留使用,如__len__()
方法1:實(shí)例方法:
實(shí)例方法是類內(nèi)部定義的函數(shù),與實(shí)例對(duì)象相關(guān)
class <類名>:
def <方法名>(self,<參數(shù)列表>):
...
實(shí)例方法采用<對(duì)象名>.<方法名>(<參數(shù)列表>)方式使用
class DemoClass:
def __init__(self,name):
self.name = name
#注:構(gòu)造函數(shù)沒(méi)有返回值
def luckey(self):
s = 0
for c in self.name:
s+=ord(c)%100
return s
dc1 = DemoClass("Wang")
dc2 = DemoClass("Li")
print(dc1.name,"'s lucky number is :",dc1.luckey())
print(dc2.name,"'s lucky number is :",dc2.luckey())
輸出:
Wang 's lucky number is : 197
Li 's lucky number is : 81
方法2:類方法:
類方法是與類對(duì)象相關(guān)的函數(shù),由所有實(shí)例對(duì)象共享
class <類名>:
@classmethod裝飾器
def <方法名>(cls,<參數(shù)列表>):
...
類方法采用<類名>.<方法名>(<參數(shù)列表>)或<對(duì)象名>.<方法名>(<參數(shù)列表>)方式使用
>類方法至少包含一個(gè)參數(shù),表示類對(duì)象,建議使用cls
>@classmethod是裝飾器,類方法定義必須要有
>類方法只能操作類屬性和其他類方法,不能操作實(shí)例屬性和實(shí)例方法
class DemoClass:
count =0
def __init__(self,name):
self.name = name
DemoClass.count +=1
#注:構(gòu)造函數(shù)沒(méi)有返回值
@classmethod
def getChrCount(cls):
s = "0123456789"
return s[DemoClass.count]
dc1 = DemoClass("Wang")
dc2 = DemoClass("Li")
print(DemoClass.getChrCount())
print(dc1.getChrCount()) #類方法是可以被實(shí)例對(duì)象調(diào)用的,因?yàn)樗鼩w類對(duì)象和實(shí)例對(duì)象共同所有
輸出:
2
2
方法3,自由方法:
是定義在類命名空間中的普通函數(shù)
class <類名>:
def <方法名>(<參數(shù)列表>):
...
#注:這里既沒(méi)有self,也沒(méi)有cls
自由方法采用<類名>.<方法名>(<參數(shù)列表>)方式使用,這時(shí)的<類名>代表的是命名空間
換句話說(shuō),自有方法是什么,它是在<類名>這個(gè)命名空間中定義的一個(gè)函數(shù),訪問(wèn)它只能用
<函數(shù)名>.方法名來(lái)訪問(wèn),
注:類對(duì)象自己獨(dú)有
>自由方法不需要self,cls這類參數(shù),可以沒(méi)有參數(shù)
>自由方法只能操作類屬性和類方法,不能操作實(shí)例屬性和實(shí)例方法
>自由方法的使用只能用<類名>
嚴(yán)格來(lái)說(shuō),自由方法就不應(yīng)該算是方法,它就是個(gè)函數(shù),只不過(guò)是定義在類的命名空間中
為了統(tǒng)一說(shuō)法,所以我們叫它自由方法,
class DemoClass:
count =0
def __init__(self,name):
self.name = name
DemoClass.count +=1
#注:構(gòu)造函數(shù)沒(méi)有返回值
def func():
DemoClass.count *=100
return DemoClass.count
dc1 = DemoClass("Wang")
print(DemoClass.func())
輸出:100
方法4:靜態(tài)方法:
我們知道,自由方法只能由類對(duì)象來(lái)使用,有沒(méi)有辦法讓實(shí)例對(duì)象使用普通的函數(shù)(沒(méi)有self,cls)呢?
可以,就是在自由方法的基礎(chǔ)上加上一個(gè)裝飾器@classmethod就可以了,
它是定義在類中的普通函數(shù),能夠被所有實(shí)例對(duì)象共享
class <類名>:
@staticmethod
def <方法名>(<參數(shù)列表>):
...
靜態(tài)方法采用<類名>.<方法名>(<參數(shù)列表>)或<對(duì)象名>.<方法名>(<參數(shù)列表>)方式使用
>靜態(tài)方法可以沒(méi)有參數(shù),可以理解為定義在類中的普通函數(shù)
>@staticmethod是裝飾器,靜態(tài)方法必須用它
>靜態(tài)方法只能操作 類屬性和其他類 方法,不能操作實(shí)例屬性和實(shí)例方法
>相比于自由方法,靜態(tài)方法能夠使用<類名>和<對(duì)象名>兩種方式調(diào)用
class DemoClass:
count =0
def __init__(self,name):
self.name = name
DemoClass.count +=1
#注:構(gòu)造函數(shù)沒(méi)有返回值
@staticmethod
def func():
DemoClass.count *=100
return DemoClass.count
dc1 = DemoClass("Wang")
print(dc1.func())
print(DemoClass.func())
記時(shí),方法3和方法4一起記
方法5:保留方法:
保留方法由雙下劃線開(kāi)始和結(jié)束的方法,保留使用
class <類名>:
def <保留方法名>(self,<參數(shù)列表>):
...
保留方法一般都對(duì)應(yīng)類的某種操作,使用操作符調(diào)用它
其實(shí)構(gòu)造函數(shù)本身也是保留方法,
class DemoClass:
count =0
def __init__(self,name):
self.name = name
DemoClass.count +=1
#注:構(gòu)造函數(shù)沒(méi)有返回值
def __len__(self):
return len(self.name)
dc1 = DemoClass("Wang")
print(len(dc1))
輸出:4
__len__ ()方法對(duì)應(yīng)內(nèi)置函數(shù)len()函數(shù)操作
理解:
這時(shí)Python解釋器保留方法,已經(jīng)對(duì)應(yīng),只需要編寫代碼即可
重寫保留方法:
class DemoClass:
count =0
def __init__(self,name):
self.name = name
DemoClass.count +=1
#注:構(gòu)造函數(shù)沒(méi)有返回值
def __len__(self):
return 5
dc1 = DemoClass("Wang")
print(len(dc1))
輸出:5
終結(jié)總結(jié):
我們可以理解為len()只能計(jì)算基本數(shù)據(jù)類型的長(zhǎng)度,對(duì)于類的長(zhǎng)度它不能計(jì)算
我們就讓他去調(diào)用類的保留方法__len__()
len(dc1)其實(shí)它還是調(diào)用的是dc1.__len__()方法
然后:這個(gè)保留方法內(nèi)部計(jì)算了一個(gè)基礎(chǔ)類型的長(zhǎng)度len(name)
(5),類的析構(gòu)函數(shù):
當(dāng)一個(gè)對(duì)象不用的時(shí)候,我們要對(duì)它釋放空間,
Python使用預(yù)定義的__del__()作為析構(gòu)函數(shù)
class <類名>:
def __del__(self):
<語(yǔ)句塊>
...
析構(gòu)函數(shù)在“真實(shí)” 刪除實(shí)例對(duì)象時(shí)被調(diào)用
“真實(shí)”后面會(huì)介紹
例子:
class DemoClass:
def __init__(self,name):
self.name = name
def __del__(self):
print("再見(jiàn)",self.name)
dc1 = DemoClass("Wang")
del dc1
輸出:
再見(jiàn)Wang
刪除對(duì)象就是使用保留字del
使用del刪除對(duì)象且對(duì)象被真實(shí)刪除 時(shí)調(diào)用析構(gòu)函數(shù)__del__()
>函數(shù)名和參數(shù):Python解釋器內(nèi)部約定,保留方法
>調(diào)用條件:當(dāng)實(shí)例對(duì)象被“真實(shí)刪除”時(shí),才調(diào)用該函數(shù)語(yǔ)句
>“真實(shí)刪除”:當(dāng)前對(duì)象的引用數(shù)為0或當(dāng)前程序退出(垃圾回收)
例子:
import time
class DemoClass:
def __init__(self,name):
self.name = name
def __del__(self):
print("再見(jiàn)",self.name)
dc1 = DemoClass("Wang")
dc2 = dc1 #引用
del dc1
print(dc2.name)
while(True):
time.sleep(1) #使程序不退出
輸出:
Wang
這就是只有當(dāng)真實(shí)刪除時(shí)才會(huì)調(diào)用析構(gòu)函數(shù)
當(dāng)然,一般構(gòu)建對(duì)象的時(shí)候,我們不用寫析構(gòu)函數(shù),python的垃圾回收機(jī)制已經(jīng)很靈活了。
Python類的內(nèi)存管理:
>在刪除對(duì)象前,Python解釋器會(huì)檢查引用次數(shù)
>檢查刪除之后是否引用次數(shù)為0,不為0則僅刪除當(dāng)前引用;為0,則刪除對(duì)象
>如果程序退出,則由垃圾回收機(jī)制刪除對(duì)象
那么如何對(duì)一個(gè)對(duì)象的引用數(shù)量進(jìn)行獲取呢?
python提供了一個(gè)sys.getrefcount(<對(duì)象名>)獲得對(duì)象的引用次數(shù)
>返回對(duì)象引用次數(shù)的方法,輔助刪除對(duì)象時(shí)的分析
>sys.getrefcount()函數(shù)返回值為 被 引用值+1
>非特定目的,不建議自己寫析構(gòu)函數(shù),利用Python垃圾回收機(jī)制就行
import sys
class DemoClass:
def __init__(self,name):
self.name = name
def __del__(self):
print("再見(jiàn)",self.name)
dc1 = DemoClass("Wang")
dc2 = dc1 #引用
print(sys.getrefcount(dc1))
輸出:3 (比真實(shí)多1)
unit3:實(shí)例1:銀行ATM等待時(shí)間分析:
需求分析:
可擴(kuò)展為泊松分布:
1 importrandom as rd2 '''
3 整體思路:4 1,需要一個(gè)全局時(shí)間5 2,以ATM每次處理結(jié)束的時(shí)間為時(shí)間驅(qū)動(dòng)事件6 3,需要一個(gè)等待隊(duì)列,維護(hù)客戶到達(dá)時(shí)間7 4,時(shí)間變化時(shí),驅(qū)動(dòng)等待隊(duì)列變化8 '''
9 classATM():10 def __init__(self,maxtime = 5):11 self.t_max =maxtime12 def getServCompleteTime(self,start= 0):#完成一次業(yè)務(wù)的時(shí)間 start 可賦值給真實(shí)的時(shí)間,
13 #這樣就是絕對(duì)的時(shí)間了
14 return start + rd.randint(1,self.t_max)15
16 classCustomers():17 def __init__(self,n):18 self.count =n19 self.left =n20 def getNextArrvTime(self,start = 0,arrvtime = 10): #下一個(gè)人到達(dá)的時(shí)間
21 if self.left !=0:22 self.left -=1
23 return start +rd.randint(1,arrvtime)24 else:25 return026 def isOver(self): #判斷n 個(gè)客戶是否都到達(dá)了
27 return True if self.left == 0 elseFalse28
29 c = Customers(100) #100個(gè)客戶
30 a =ATM()31 wait_list =[] #存放用戶到達(dá)時(shí)間
32 wait_time =0 #總共等待時(shí)間
33 cur_time= 0 #當(dāng)前時(shí)間
34 cur_time +=c.getNextArrvTime()35 wait_list.append(cur_time)36 while len(wait_list) !=0 or notc.isOver():37 if wait_list[0] <= cur_time: #用戶提前到了
38 next_time = a.getServCompleteTime(cur_time) #下次時(shí)間
39 delwait_list[0]40 else:41 next_time = cur_time +1
42
43 if not c.isOver() and len(wait_list) ==0:44 next_arrv =c.getNextArrvTime(cur_time)45 wait_list.append(next_arrv)46
47 if not c.isOver() and wait_list[-1]
<
<<
<
<
<<
<
<<<<
<
<<
<
<<
<
<<
<
<<
<<<<
<
<<
<
<
<
<
<<
<
<
<<
<<
<<
<<<
<
<
<
<<&
<
&other
<<
<
<<
<<<<<
<<
<
<
<
<<
<
<
<
總結(jié)
以上是生活随笔為你收集整理的python面向对象生动讲解_Python面向对象语法精讲的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python3.7.3 离线安装para
- 下一篇: git查看 对比未提交_30分钟让你掌握