天天看點

79_類方法83.類方法靜态方法差別

83.類方法

staticmethod 官方文檔

classmethod 官方文檔

類方法是從屬于

“類對象”的方法

。類方法通過裝飾器

@classmethod

來定義,格式如下:

@classmethod 
def 類方法名(cls [,形參清單]) : 
    函數體
    # 可以了解為 無需執行個體化對象。就可以直接通過 類名.方法名() 來通路的方法 
           

要點如下:

  1. @classmethod

    必須位于方法上面一行
  2. 第一個

    cls

    必須有;

    cls

    指的就是

    “類對象”

    本身;(和

    self

    指的是

    執行個體對象

    本身有異曲同工之處)
  3. 調用類方法格式

    :“類名.類方法名(參數清單)”

    。 參數清單中,不需要也不能給

    cls

    傳 值。
  4. 類方法中

    通路執行個體屬性

    執行個體方法

    會導緻

    錯誤

  5. 子類繼承父類方法

    時,傳入

    cls

    是子類對象,而

    非父類對象

    【操作】類方法使用測試
# 類方法   從屬于   類(模具)的  方法

class Student02:
    company = '海賊王'  # 類屬性
    @classmethod  # 建立 執行個體對象之後  類(模具) 方法不會建立在 執行個體對象裡面
    def printCompany(cls):
        print(cls.company)
        
Student02.printCompany()
           

靜态方法

Python中允許定義與“類對象”無關的方法,稱為“靜态方法”。

靜态方法”和在子產品中定義普通函數沒有差別,隻不過“靜态方法”放到了“類的名字空 間裡面”,需要通過“類調用”。

靜态方法通過裝飾器

@staticmethod

來定義,

格式如下:

@staticmethod 
def 靜态方法名([形參清單]) : 
    函數體 
           

要點如下:

  1. @staticmethod

    必須位于方法上面一行
  2. 調用靜态方法格式:“類名.靜态方法名(參數清單)”。
  3. 靜态方法中

    通路執行個體屬性

    執行個體方法

    導緻錯誤

【操作】靜态方法使用測試

class Student03:
    company = '海賊王'  # 類屬性

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

    @staticmethod
    def add(a, b):  # 靜态方法
        print(Student03.company)  # 靜态方法  裡面 也可以調用  類屬性
        print('{0}+{1}={2}'.format(a, b, (a + b)))
        return a + b   # 類方法 和 靜态方法中,不能調用 執行個體變量和執行個體方法
        # 模具裡 想吃餅幹(執行個體對象和方法),不可以, 也就是 無法傳遞 self


Student03.add(20, 30)

           

差別

這兩個方法的用法是類似的,在上面的例子中大多數情況下,

classmethod

也可以通過

staticmethod

代替,在通過類調用時,這兩者對于調用者來說是不可區分的。

這兩者的差別在于,

classmethod

增加了一個對

實際調用類

引用

,這帶來了很多友善的地方:
  • 方法可以判斷出自己是通過基類被調用,還是通過某個子類被調用
  • 通過子類調用時,方法可以傳回子類的執行個體而非基類的執行個體
  • 通過子類調用時,方法可以調用子類的其他

    classmethod

  • 一般來說

    classmethod

    可以完全替代

    staticmethod

staticmethod

唯一的好處是調用時它傳回的是一個

真正的函數

,而且每次調用時

傳回同一個執行個體

classmethod

則會對

基類

子類

傳回不同的

bound method

執行個體),但這點幾乎從來沒有什麼時候是有用的。

不過,

staticmethod

可以在子類上被

重寫為classmethod

,反之亦然 。

繼續閱讀