類屬性和類方法
目標(biāo)
- 類的結(jié)構(gòu)
- 類屬性和實(shí)例屬性
- 類方法和靜態(tài)方法
01. 類的結(jié)構(gòu)
1.1 術(shù)語 —— 實(shí)例
- 使用面相對象開發(fā)媒咳,第 1 步 是設(shè)計(jì) 類
- 使用 類名() 創(chuàng)建對象钠惩,創(chuàng)建對象 的動(dòng)作有兩步:
- 在內(nèi)存中為對象 分配空間
- 調(diào)用初始化方法
__init__
為 對象初始化
- 調(diào)用初始化方法
- 對象創(chuàng)建后,內(nèi)存 中就有了一個(gè)對象的 實(shí)實(shí)在在 的存在 —— 實(shí)例
因此当宴,通常也會(huì)把:
- 創(chuàng)建出來的 對象 叫做 類 的 實(shí)例
- 創(chuàng)建對象的 動(dòng)作 叫做 實(shí)例化
- 對象的屬性 叫做 實(shí)例屬性
- 對象調(diào)用的方法 叫做 實(shí)例方法
在程序執(zhí)行時(shí):
- 對象各自擁有自己的 實(shí)例屬性
- 調(diào)用對象方法,可以通過
self.
- 訪問自己的屬性
- 調(diào)用自己的方法
結(jié)論
- 每一個(gè)對象 都有自己 獨(dú)立的內(nèi)存空間驴党,保存各自不同的屬性
- 多個(gè)對象的方法辆它,在內(nèi)存中只有一份誊薄,在調(diào)用方法時(shí),需要把對象的引用 傳遞到方法內(nèi)部
1.2 類是一個(gè)特殊的對象
Python
中 一切皆對象:
class AAA:
定義的類屬于 類對象obj1 = AAA()
屬于 實(shí)例對象
- 在程序運(yùn)行時(shí)娩井,類 同樣 會(huì)被加載到內(nèi)存
- 在
Python
中暇屋,類 是一個(gè)特殊的對象 —— 類對象 - 在程序運(yùn)行時(shí),類對象 在內(nèi)存中 只有一份洞辣,使用 一個(gè)類 可以創(chuàng)建出 很多個(gè)對象實(shí)例
- 除了封裝 實(shí)例 的 屬性 和 方法外,類對象 還可以擁有自己的 屬性 和 方法
- 類屬性
- 類方法
- 通過 類名. 的方式可以 訪問類的屬性 或者 調(diào)用類的方法
02. 類屬性和實(shí)例屬性
2.1 概念和使用
- 類屬性 就是給 類對象 中定義的 屬性
- 通常用來記錄 與這個(gè)類相關(guān) 的特征
- 類屬性 不會(huì)用于記錄 具體對象的特征
示例需求
- 定義一個(gè) 工具類
- 每件工具都有自己的
name
-
需求 —— 知道使用這個(gè)類墨闲,創(chuàng)建了多少個(gè)工具對象腺办?
class Tool(object):
# 使用賦值語句处嫌,定義類屬性,記錄創(chuàng)建工具對象的總數(shù)
count = 0
def __init__(self, name):
self.name = name
# 針對類屬性做一個(gè)計(jì)數(shù)+1
Tool.count += 1
# 創(chuàng)建工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("鐵鍬")
# 知道使用 Tool 類到底創(chuàng)建了多少個(gè)對象?
print("現(xiàn)在創(chuàng)建了 %d 個(gè)工具" % Tool.count)
2.2 屬性的獲取機(jī)制(科普)
- 在
Python
中 屬性的獲取 存在一個(gè) 向上查找機(jī)制
- 因此著瓶,要訪問類屬性有兩種方式:
- 類名.類屬性
- 對象.類屬性 (不推薦)
注意
- 如果使用
對象.類屬性 = 值
賦值語句,只會(huì) 給對象添加一個(gè)屬性啼县,而不會(huì)影響到 類屬性的值
03. 類方法和靜態(tài)方法
3.1 類方法
-
類屬性 就是針對 類對象 定義的屬性
- 使用 賦值語句 在
class
關(guān)鍵字下方可以定義 類屬性 - 類屬性 用于記錄 與這個(gè)類相關(guān) 的特征
- 使用 賦值語句 在
-
類方法 就是針對 類對象 定義的方法
- 在 類方法 內(nèi)部可以直接訪問 類屬性 或者調(diào)用其他的 類方法
語法如下
@classmethod
def 類方法名(cls):
pass
- 類方法需要用 修飾器
@classmethod
來標(biāo)識(shí)材原,告訴解釋器這是一個(gè)類方法 - 類方法的 第一個(gè)參數(shù) 應(yīng)該是
cls
- 由 哪一個(gè)類 調(diào)用的方法,方法內(nèi)的
cls
就是 哪一個(gè)類的引用 - 這個(gè)參數(shù)和 實(shí)例方法 的第一個(gè)參數(shù)是
self
類似 -
提示 使用其他名稱也可以季眷,不過習(xí)慣使用
cls
- 由 哪一個(gè)類 調(diào)用的方法,方法內(nèi)的
- 通過 類名. 調(diào)用 類方法余蟹,調(diào)用方法時(shí),不需要傳遞
cls
參數(shù) -
在方法內(nèi)部
- 可以通過
cls.
訪問類的屬性 - 也可以通過
cls.
調(diào)用其他的類方法
- 可以通過
示例需求
- 定義一個(gè) 工具類
- 每件工具都有自己的
name
-
需求 —— 在 類 封裝一個(gè)
show_tool_count
的類方法子刮,輸出使用當(dāng)前這個(gè)類威酒,創(chuàng)建的對象個(gè)數(shù)
@classmethod
def show_tool_count(cls):
"""顯示工具對象的總數(shù)"""
print("工具對象的總數(shù) %d" % cls.count)
在類方法內(nèi)部,可以直接使用
cls
訪問 類屬性 或者 調(diào)用類方法
3.2 靜態(tài)方法
-
在開發(fā)時(shí)挺峡,如果需要在 類 中封裝一個(gè)方法葵孤,這個(gè)方法:
- 既 不需要 訪問 實(shí)例屬性 或者調(diào)用 實(shí)例方法
- 也 不需要 訪問 類屬性 或者調(diào)用 類方法
這個(gè)時(shí)候,可以把這個(gè)方法封裝成一個(gè) 靜態(tài)方法
語法如下
@staticmethod
def 靜態(tài)方法名():
pass
-
靜態(tài)方法 需要用 修飾器
@staticmethod
來標(biāo)識(shí)橱赠,告訴解釋器這是一個(gè)靜態(tài)方法 - 通過 類名. 調(diào)用 靜態(tài)方法
class Dog(object):
# 狗對象計(jì)數(shù)
dog_count = 0
@staticmethod
def run():
# 不需要訪問實(shí)例屬性也不需要訪問類屬性的方法
print("狗在跑...")
def __init__(self, name):
self.name = name
3.3 方法綜合案例
需求
- 設(shè)計(jì)一個(gè)
Game
類 - 屬性:
- 定義一個(gè) 類屬性
top_score
記錄游戲的 歷史最高分 - 定義一個(gè) 實(shí)例屬性
player_name
記錄 當(dāng)前游戲的玩家姓名
- 定義一個(gè) 類屬性
- 方法:
-
靜態(tài)方法
show_help
顯示游戲幫助信息 -
類方法
show_top_score
顯示歷史最高分 -
實(shí)例方法
start_game
開始當(dāng)前玩家的游戲
-
靜態(tài)方法
- 主程序步驟
- 查看幫助信息
- 查看歷史最高分
- 創(chuàng)建游戲?qū)ο笥热裕_始游戲
案例小結(jié)
-
實(shí)例方法 —— 方法內(nèi)部需要訪問 實(shí)例屬性
- 實(shí)例方法 內(nèi)部可以使用 類名. 訪問類屬性
- 類方法 —— 方法內(nèi)部 只 需要訪問 類屬性
- 靜態(tài)方法 —— 方法內(nèi)部,不需要訪問 實(shí)例屬性 和 類屬性
提問
如果方法內(nèi)部 即需要訪問 實(shí)例屬性狭姨,又需要訪問 類屬性宰啦,應(yīng)該定義成什么方法鲤嫡?
答案
- 應(yīng)該定義 實(shí)例方法
- 因?yàn)椋?strong>類只有一個(gè),在 實(shí)例方法 內(nèi)部可以使用 類名. 訪問類屬性
class Game(object):
# 游戲最高分绑莺,類屬性
top_score = 0
@staticmethod
def show_help():
print("幫助信息:讓僵尸走進(jìn)房間")
@classmethod
def show_top_score(cls):
print("游戲最高分是 %d" % cls.top_score)
def __init__(self, player_name):
self.player_name = player_name
def start_game(self):
print("[%s] 開始游戲..." % self.player_name)
# 使用類名.修改歷史最高分
Game.top_score = 999
# 1. 查看游戲幫助
Game.show_help()
# 2. 查看游戲最高分
Game.show_top_score()
# 3. 創(chuàng)建游戲?qū)ο笈郏_始游戲
game = Game("小明")
game.start_game()
# 4. 游戲結(jié)束,查看游戲最高分
Game.show_top_score()