類
基礎(chǔ)術(shù)語
- 使用 類名() 創(chuàng)建對象,**創(chuàng)建對象 **的動作有兩步
- 在內(nèi)存中為對象 分配空間
- 調(diào)用初始化方法 init 為對象初始化
- 對象創(chuàng)建后,內(nèi)存中就有了一個對象的** 實(shí)例**
- 通常會把
- 創(chuàng)建出來的 對象 叫做 類 的實(shí)例
- 創(chuàng)建對象的 **動作 **叫做 實(shí)例化
- 對象的屬性 叫做** 實(shí)例屬性**
- 在程序執(zhí)行時(shí)
- 對象各自擁有自己的 實(shí)例屬性
- 調(diào)用對象方法,可以通過 self. 訪問自己的屬性或方法
- 每一個對象 都有一個自己獨(dú)立的內(nèi)存空間,互不干涉
- 多個對象的方法, 在內(nèi)存中只有一份 ,在調(diào)用方法時(shí),需要把對象的引用傳遞到方法內(nèi)部
類是一個特殊的對象
- Python 中 一切皆對象
- 類是一個特殊的對象,同樣會被加載到內(nèi)存中,類對象在內(nèi)存中只有一份
- 一個類可以創(chuàng)建出多個對象實(shí)例
- 除了封裝** 實(shí)例 的屬性和方法**外,類對象還可以擁有自己的屬性和方法
- 通過** 類名.** 的方式可以訪問類的屬性和方法
示例
class Animal:
# 定義一個 類 屬性
count=0
def __init__(self,name):
self.name=name
Animal.count=Animal.count+1
animal1=Animal("小白")
animal2=Animal("小黑")
animal3=Animal("小綠")
print("查看類屬性的變化次數(shù):%d" %Animal.count)
輸出結(jié)果
類方法
- **類方法 就是針對 類對象 **定義的方法
- 在類方法 內(nèi)部可以直接訪問 類屬性 或者調(diào)用其他的 類方法
- 類方法需要用** 修飾器 @classmethod **來標(biāo)識,告訴解釋器這是一個 類方法
- 類方法的 第一個參數(shù) 應(yīng)該是 cls
- 由 哪一個類調(diào)用的方法 ,方法內(nèi)的 cls ,就是哪一個類的引用
- 這個參數(shù)和 實(shí)例方法的第一個參數(shù) self 類似
- 不使用 cls ,使用其他名稱也可以,習(xí)慣問題
- 通過 **類名. **調(diào)用類方法,不需要傳遞 cls 參數(shù)
- 在方法內(nèi)部,可以通過** cls.** 訪問類的屬性或類的方法
**語法
**
@classmethod
def 類方法名(cls):
pass
示例
class Animal:
# 定義一個 類 屬性
count=0
def __init__(self,name):
self.name=name
Animal.count=Animal.count+1
# 定義一個 類 方法
@classmethod
def show_count(cls):
print("我是類方法,類屬性的值是:%d"%cls.count)
Animal("小白")
Animal("小黑")
# 調(diào)用類 方法
Animal.show_count()
輸出結(jié)果
靜態(tài)方法
- 使用修飾器 @staticmethod 來標(biāo)識
- 通過 **類名. **調(diào)用 靜態(tài)方法
- 使用場景
- 不需要訪問** 實(shí)例屬性** 或者調(diào)用** 實(shí)例方法**
- 不需要訪問** 類屬性** 或者調(diào)用 類方法
語法
@staticmethod
def 靜態(tài)方法名():
pass
示例
class Person:
# 定義類屬性
count=0
def __init__(self,name):
self.name=name
# 定義一個靜態(tài)方法,靜態(tài)方法不能調(diào)用 類方法或?qū)傩?與 實(shí)例方法或?qū)傩?/span>
@staticmethod
def static_test():
print("我是一個靜態(tài)方法,不能調(diào)用類方法與屬性 和實(shí)例方法與屬性")
# 靜態(tài)方法直接用 類名調(diào)用
Person.static_test()
輸出結(jié)果
綜合練習(xí)示例
"""
需求:窗口取票
票數(shù)是共有的
每個人取的數(shù)量不一樣
操作提示信息,不與任何屬性或方法關(guān)聯(lián)
"""
class Ticket:
# 總共 10 張票
totalTicket=10
def __init__(self,name):
self.name=name
# 操作說明,可以使用靜態(tài)方法實(shí)現(xiàn)
@staticmethod
def show_instructions():
print("操作說明:取票的數(shù)量不能超過票總數(shù)量!!!")
# 顯示總票數(shù),可以使用 類方法
@classmethod
def show_ticket(cls):
print("還剩余的票數(shù)有:%s 張" %cls.totalTicket)
# 取票,可以使用實(shí)例方法
def take_ticket(self,num):
Ticket.totalTicket=Ticket.totalTicket-num
print("%s 取走了 %d 張票..."%(self.name,num))
# 取票的操作說明
Ticket.show_instructions()
# 開始取票,張三 取3張, 李四取4張
zs=Ticket("張三")
zs.take_ticket(3)
#查看剩余票數(shù)
Ticket.show_ticket()
ls=Ticket("李四")
ls.take_ticket(4)
#查看剩余票數(shù)
Ticket.show_ticket()
輸出結(jié)果
單例模式
設(shè)計(jì)模式
- **設(shè)計(jì)模式 **是針對某一特定問題的解決方案,由人們總結(jié)和提煉的
- 使用設(shè)計(jì)模式 是為了可重用代碼, 使代碼更容易理解,保證代碼可靠性
- 單例設(shè)計(jì)模式
- 目的: 讓類創(chuàng)建的對象,在系統(tǒng)中只有 唯一一個
- 每一次執(zhí)行 **類名() **返回的內(nèi)存地址引用,都是同一個
**__new__方法
**
- 使用 類名() 創(chuàng)建對象時(shí), Python的解釋器首先會調(diào)用** new **方法為對象 分配內(nèi)存空間
- Python的解釋器獲得對象的引用后,將引用作為第一個參數(shù),傳遞給 **init **方法
- 重寫 new 方法的代碼非常固定
- 重寫 new 方法一定要 return super(). new (cls)
- 否則 Python的解釋器 得不到對象引用,就不會調(diào)用初始化方法
- **new **是一個 靜態(tài)方法 ,在調(diào)用時(shí)需要 主動傳遞 cls 參數(shù)
示例
class SingleClass():
# 定義類實(shí)例對象
instants=None
# 重寫 __new__ 方法
def __new__(cls,*agrs,**kwargs):
print("創(chuàng)建對象方法.....")
if SingleClass.instants== None:
# 初始化實(shí)例對象,調(diào)用父類方法
SingleClass.instants=super().__new__(cls)
return SingleClass.instants
def __init__(self):
print("初始化方法。。。。")
# 單例模式 ,不管創(chuàng)建多少次實(shí)例,實(shí)際上都是同一個
s1=SingleClass()
s2=SingleClass()
s3=SingleClass()
print(s1)
print(s2)
print(s3)
輸出結(jié)果
以上的方法雖然解決了對象只會創(chuàng)建一次的問題,但是初始化的方法還會調(diào)用多次,消耗內(nèi)存。 此處可以 增加一個 initFlag 的標(biāo)記,一但初始化后就打上標(biāo)記,以后就不再進(jìn)行初始化。 改造代碼如下:
class SingleClass():
# 定義類實(shí)例對象
instants=None
# 定義一個初始化標(biāo)記
initFlag=False
# 重寫 __new__ 方法
def __new__(cls,*agrs,**kwargs):
if SingleClass.instants== None:
print("創(chuàng)建對象方法.....")
# 初始化實(shí)例對象,調(diào)用父類方法
SingleClass.instants=super().__new__(cls)
return SingleClass.instants
def __init__(self):
if SingleClass.initFlag:
return
print("初始化方法。。。。")
SingleClass.initFlag=True
# 單例模式 ,不管創(chuàng)建多少次實(shí)例,實(shí)際上都是同一個
s1=SingleClass()
s2=SingleClass()
s3=SingleClass()
print(s1)
print(s2)
print(s3)
**輸出結(jié)果
**
-
內(nèi)存
+關(guān)注
關(guān)注
8文章
3121瀏覽量
75241 -
對象
+關(guān)注
關(guān)注
1文章
38瀏覽量
17545 -
空間
+關(guān)注
關(guān)注
2文章
50瀏覽量
13874
發(fā)布評論請先 登錄
評論