目標
- 類的結(jié)構(gòu)
- 類屬性和實例屬性
- 類方法和靜態(tài)方法
01. 類的結(jié)構(gòu)
1.1 術(shù)語 —— 實例
使用面相對象開發(fā),第 1 步 是設(shè)計 類
-
使用 類名() 創(chuàng)建對象,創(chuàng)建對象 的動作有兩步:
- 在內(nèi)存中為對象 分配空間
- 調(diào)用初始化方法 init 為 對象初始化
-
對象創(chuàng)建后,內(nèi)存 中就有了一個對象的 實實在在 的存在 —— 實例
因此扣孟,通常也會把:
創(chuàng)建出來的 對象 叫做 類 的 實例
創(chuàng)建對象的 動作 叫做 實例化
對象的屬性 叫做 實例屬性
對象調(diào)用的方法 叫做 實例方法
在程序執(zhí)行時:對象各自擁有自己的 實例屬性
調(diào)用對象方法胆描,可以通過 self.
- 訪問自己的屬性
- 調(diào)用自己的方法
結(jié)論
-
每一個對象
都有自己獨立的內(nèi)存空間
,保存各自不同的屬性 -
多個對象的方法粗蔚,在內(nèi)存中只有一份
,在調(diào)用方法時饶火,需要把對象的引用 傳遞到方法內(nèi)部
1.2 類是一個特殊的對象
Python 中 一切皆對象:
class AAA: 定義的類屬于 類對象
obj1 = AAA() 屬于 實例對象
- 在程序運行時鹏控,類 同樣 會被加載到內(nèi)存
- 在 Python 中,類 是一個特殊的對象 —— 類對象
- 在程序運行時肤寝,類對象 在內(nèi)存中 只有一份当辐,使用 一個類 可以創(chuàng)建出 很多個對象實例
- 除了封裝 實例 的 屬性 和 方法外,類對象 還可以擁有自己的 屬性 和 方法
- 類屬性
- 類方法
-
通過 類名. 的方式可以 訪問類的屬性 或者 調(diào)用類的方法
02. 類屬性和實例屬性
2.1 概念和使用
- 類屬性 就是給 類對象 中定義的 屬性
- 通常用來記錄 與這個類相關(guān) 的特征
- 類屬性 不會用于記錄 具體對象的特征
示例需求
- 定義一個 工具類
- 每件工具都有自己的 name
-
需求 —— 知道使用這個類鲤看,創(chuàng)建了多少個工具對象缘揪?
class Tool(object):
# 使用賦值語句,定義類屬性,記錄創(chuàng)建工具對象的總數(shù)
count = 0
def __init__(self, name):
self.name = name
# 針對類屬性做一個計數(shù)+1
Tool.count += 1
# 創(chuàng)建工具對象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("鐵鍬")
# 知道使用 Tool 類到底創(chuàng)建了多少個對象?
print("現(xiàn)在創(chuàng)建了 %d 個工具" % Tool.count)
2.2 屬性的獲取機制(科普)
-
在 Python 中 屬性的獲取 存在一個 向上查找機制
- 因此找筝,要訪問類屬性有兩種方式:
- 類名.類屬性
- 對象.類屬性 (不推薦)
注意
- 如果使用 對象.類屬性 = 值 賦值語句蹈垢,只會 給對象添加一個屬性,而不會影響到 類屬性的值
03. 類方法和靜態(tài)方法
3.1 類方法
- 類屬性 就是針對 類對象 定義的屬性
- 使用 賦值語句 在 class 關(guān)鍵字下方可以定義 類屬性
- 類屬性 用于記錄 與這個類相關(guān) 的特征
- 類方法 就是針對 類對象 定義的方法
- 在 類方法 內(nèi)部可以直接訪問 類屬性 或者調(diào)用其他的 類方法
語法如下
@classmethod
def 類方法名(cls):
pass
類方法需要用 修飾器 @classmethod 來標識袖裕,告訴解釋器這是一個類方法
-
類方法的 第一個參數(shù) 應(yīng)該是 cls
- 由 哪一個類 調(diào)用的方法曹抬,方法內(nèi)的 cls 就是 哪一個類的引用
- 這個參數(shù)和 實例方法 的第一個參數(shù)是 self 類似
- 提示 使用其他名稱也可以,不過習慣使用 cls
通過 類名. 調(diào)用 類方法急鳄,調(diào)用方法時谤民,不需要傳遞 cls 參數(shù)
-
在方法內(nèi)部
- 可以通過 cls. 訪問類的屬性
- 也可以通過 cls. 調(diào)用其他的類方法
示例需求
- 定義一個 工具類
- 每件工具都有自己的 name
-
需求 —— 在 類 封裝一個 show_tool_count 的類方法,輸出使用當前這個類疾宏,創(chuàng)建的對象個數(shù)
@classmethod
def show_tool_count(cls):
"""顯示工具對象的總數(shù)"""
print("工具對象的總數(shù) %d" % cls.count)
在類方法內(nèi)部赖临,可以直接使用 cls 訪問 類屬性 或者 調(diào)用類方法
3.2 靜態(tài)方法
-
在開發(fā)時,如果需要在 類 中封裝一個方法灾锯,這個方法:
- 既 不需要 訪問 實例屬性 或者調(diào)用 實例方法
- 也 不需要 訪問 類屬性 或者調(diào)用 類方法
這個時候兢榨,可以把這個方法封裝成一個 靜態(tài)方法
語法如下
@staticmethod
def 靜態(tài)方法名():
pass
- 靜態(tài)方法 需要用 修飾器 @staticmethod 來標識,告訴解釋器這是一個靜態(tài)方法
- 通過 類名. 調(diào)用 靜態(tài)方法
class Dog(object):
# 狗對象計數(shù)
dog_count = 0
@staticmethod
def run():
# 不需要訪問實例屬性也不需要訪問類屬性的方法
print("狗在跑...")
def __init__(self, name):
self.name = name
3.3 方法綜合案例
- 設(shè)計一個 Game 類
- 屬性:
- 定義一個 類屬性 top_score 記錄游戲的 歷史最高分
- 定義一個 實例屬性 player_name 記錄 當前游戲的玩家姓名
- 方法:
- 靜態(tài)方法 show_help 顯示游戲幫助信息
- 類方法 show_top_score 顯示歷史最高分
- 實例方法 start_game 開始當前玩家的游戲
- 主程序步驟
- 查看幫助信息
- 查看歷史最高分
-
創(chuàng)建游戲?qū)ο笏骋_始游戲
-
案例小結(jié)
- 實例方法 —— 方法內(nèi)部需要訪問 實例屬性
- 實例方法 內(nèi)部可以使用 類名. 訪問類屬性
- 類方法 —— 方法內(nèi)部 只 需要訪問 類屬性
- 靜態(tài)方法 —— 方法內(nèi)部吵聪,不需要訪問 實例屬性 和 類屬性
提問
- 如果方法內(nèi)部 即需要訪問 實例屬性,又需要訪問 類屬性兼雄,應(yīng)該定義成什么方法吟逝?
答案
- 應(yīng)該定義 實例方法
- 因為,類只有一個赦肋,在 實例方法 內(nèi)部可以使用 類名. 訪問類屬性
class Game(object):
# 游戲最高分块攒,類屬性
top_score = 0
@staticmethod
def show_help():
print("幫助信息:讓僵尸走進房間")
@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()