python 類屬性和類方法

類屬性和類方法

目標(biāo)

  • 類的結(jié)構(gòu)
  • 類屬性和實(shí)例屬性
  • 類方法和靜態(tài)方法

01. 類的結(jié)構(gòu)

1.1 術(shù)語 —— 實(shí)例

  1. 使用面相對(duì)象開發(fā),第 1 步 是設(shè)計(jì)
  2. 使用 類名() 創(chuàng)建對(duì)象,創(chuàng)建對(duì)象 的動(dòng)作有兩步:
      1. 在內(nèi)存中為對(duì)象 分配空間
      1. 調(diào)用初始化方法 __init__對(duì)象初始化
  3. 對(duì)象創(chuàng)建后,內(nèi)存 中就有了一個(gè)對(duì)象的 實(shí)實(shí)在在 的存在 —— 實(shí)例
[圖片上傳中...(017_類的結(jié)構(gòu)示意圖II.png-fb3cdf-1544248635513-0)]

因此,通常也會(huì)把:

  1. 創(chuàng)建出來的 對(duì)象 叫做 實(shí)例
  2. 創(chuàng)建對(duì)象的 動(dòng)作 叫做 實(shí)例化
  3. 對(duì)象的屬性 叫做 實(shí)例屬性
  4. 對(duì)象調(diào)用的方法 叫做 實(shí)例方法

在程序執(zhí)行時(shí):

  1. 對(duì)象各自擁有自己的 實(shí)例屬性
  2. 調(diào)用對(duì)象方法,可以通過 self.
    • 訪問自己的屬性
    • 調(diào)用自己的方法

結(jié)論

  • 每一個(gè)對(duì)象 都有自己 獨(dú)立的內(nèi)存空間保存各自不同的屬性
  • 多個(gè)對(duì)象的方法,在內(nèi)存中只有一份,在調(diào)用方法時(shí),需要把對(duì)象的引用 傳遞到方法內(nèi)部

1.2 類是一個(gè)特殊的對(duì)象

Python一切皆對(duì)象

  • class AAA: 定義的類屬于 類對(duì)象
  • obj1 = AAA() 屬于 實(shí)例對(duì)象
  • 在程序運(yùn)行時(shí), 同樣 會(huì)被加載到內(nèi)存
  • Python 中, 是一個(gè)特殊的對(duì)象 —— 類對(duì)象
  • 在程序運(yùn)行時(shí),類對(duì)象 在內(nèi)存中 只有一份,使用 一個(gè)類 可以創(chuàng)建出 很多個(gè)對(duì)象實(shí)例
  • 除了封裝 實(shí)例屬性方法外,類對(duì)象 還可以擁有自己的 屬性方法
    1. 類屬性
    2. 類方法
  • 通過 類名. 的方式可以 訪問類的屬性 或者 調(diào)用類的方法
017_類的結(jié)構(gòu)示意圖II.png

02. 類屬性和實(shí)例屬性

2.1 概念和使用

  • 類屬性 就是給 類對(duì)象 中定義的 屬性
  • 通常用來記錄 與這個(gè)類相關(guān) 的特征
  • 類屬性 不會(huì)用于記錄 具體對(duì)象的特征

示例需求

  • 定義一個(gè) 工具類
  • 每件工具都有自己的 name
  • 需求 —— 知道使用這個(gè)類,創(chuàng)建了多少個(gè)工具對(duì)象?
    018_類屬性案例I.png
class Tool(object):

    # 使用賦值語句,定義類屬性,記錄創(chuàng)建工具對(duì)象的總數(shù)
    count = 0

    def __init__(self, name):
        self.name = name

        # 針對(duì)類屬性做一個(gè)計(jì)數(shù)+1
        Tool.count += 1


# 創(chuàng)建工具對(duì)象
tool1 = Tool("斧頭")
tool2 = Tool("榔頭")
tool3 = Tool("鐵鍬")

# 知道使用 Tool 類到底創(chuàng)建了多少個(gè)對(duì)象?
print("現(xiàn)在創(chuàng)建了 %d 個(gè)工具" % Tool.count)

2.2 屬性的獲取機(jī)制(科普)

  • Python屬性的獲取 存在一個(gè) 向上查找機(jī)制
019_通過對(duì)象訪問類屬性.png
  • 因此,要訪問類屬性有兩種方式:
    1. 類名.類屬性
    2. 對(duì)象.類屬性 (不推薦)

注意

  • 如果使用 對(duì)象.類屬性 = 值 賦值語句,只會(huì) 給對(duì)象添加一個(gè)屬性,而不會(huì)影響到 類屬性的值

03. 類方法和靜態(tài)方法

3.1 類方法

  • 類屬性 就是針對(duì) 類對(duì)象 定義的屬性
    • 使用 賦值語句class 關(guān)鍵字下方可以定義 類屬性
    • 類屬性 用于記錄 與這個(gè)類相關(guān) 的特征
  • 類方法 就是針對(duì) 類對(duì)象 定義的方法
    • 類方法 內(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
  1. 通過 類名. 調(diào)用 類方法調(diào)用方法時(shí),不需要傳遞 cls 參數(shù)
  2. 在方法內(nèi)部
    • 可以通過 cls. 訪問類的屬性
    • 也可以通過 cls. 調(diào)用其他的類方法

示例需求

  • 定義一個(gè) 工具類
  • 每件工具都有自己的 name
  • 需求 —— 在 封裝一個(gè) show_tool_count 的類方法,輸出使用當(dāng)前這個(gè)類,創(chuàng)建的對(duì)象個(gè)數(shù)
    020_類方法案例.png
@classmethod
def show_tool_count(cls):
    """顯示工具對(duì)象的總數(shù)"""
    print("工具對(duì)象的總數(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):
    
    # 狗對(duì)象計(jì)數(shù)
    dog_count = 0
    
    @staticmethod
    def run():
        
        # 不需要訪問實(shí)例屬性也不需要訪問類屬性的方法
        print("狗在跑...")

    def __init__(self, name):
        self.name = name
        

3.3 方法綜合案例

需求

  1. 設(shè)計(jì)一個(gè) Game
  2. 屬性:
    • 定義一個(gè) 類屬性 top_score 記錄游戲的 歷史最高分
    • 定義一個(gè) 實(shí)例屬性 player_name 記錄 當(dāng)前游戲的玩家姓名
  3. 方法:
    • 靜態(tài)方法 show_help 顯示游戲幫助信息
    • 類方法 show_top_score 顯示歷史最高分
    • 實(shí)例方法 start_game 開始當(dāng)前玩家的游戲
  4. 主程序步驟
      1. 查看幫助信息
      1. 查看歷史最高分
      1. 創(chuàng)建游戲?qū)ο?,開始游戲
021_方法綜合案例.png

案例小結(jié)

  1. 實(shí)例方法 —— 方法內(nèi)部需要訪問 實(shí)例屬性
    • 實(shí)例方法 內(nèi)部可以使用 類名. 訪問類屬性
  2. 類方法 —— 方法內(nèi)部 需要訪問 類屬性
  3. 靜態(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()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容