Python常見面試題006 類方法、類例項方法、靜態方法有何區別?

松勤吳老師發表於2023-02-25

006. Python中類方法、類例項方法、靜態方法有何區別?

全部放一個裡面篇幅過大了,就拆分成1個個釋出

示例程式碼

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

    def say(self):
        print(f'我的名字是{self.name}')

    @classmethod
    def walk(self):
        print('類方法 walk')

    @staticmethod
    def sleep():
        print('類靜態方法 sleep')

一般這樣呼叫

# 類名.類方法
Human.walk()

# 例項名.例項方法
wuxianfeng = Human('wuxianfeng')
wuxianfeng.say()

# 靜態方法則無所謂
Human.sleep()
wuxianfeng.sleep()

問題就是,例項能否呼叫類方法?類能否呼叫例項方法呢?

  • 例項能否呼叫類方法:能,比如wuxianfeng.walk()

  • 類能否呼叫例項方法:不能,比如Human.say()

    TypeError: say() missing 1 required positional argument: 'self'
    

小結

方法 裝飾器 引數 呼叫方
類方法 @classmethod cls 類,例項(不推薦)
例項方法 self 例項
靜態方法 @staticmethod 無預設引數 類(推薦),例項(不推薦)

cls代指類本身,self代指例項

class Person:
    @classmethod
    def eat(cls): # 這裡的cls就是指Person
        pass
    def drink(self): # 這裡的self就是指Person()出來的例項
        pass

cls和self這2個名字只是約定,見名知義,不建議更改,IDE會給你提示,其他地方需要自己注意,事實上你可以寫成任意的名字,但不推薦

class Person:
    @classmethod
    def eat(class_name): 
        print('eat')
    def drink(instance_name):
        print('drink')
Person.eat()   # 沒毛病
Person().drink()  # 沒毛病

pycharm中的提示資訊

官網

@classmethod

把一個方法封裝成類方法。

一個類方法把類自己作為第一個實參,就像一個例項方法把例項自己作為第一個實參。請用以下習慣來宣告類方法:

class C:
    @classmethod
    def f(cls, arg1, arg2): ...

@classmethod 這樣的形式稱為函式的 decorator

類方法的呼叫可以在類上進行 (例如 C.f()) 也可以在例項上進行 (例如 C().f())。 其所屬類以外的類例項會被忽略。 如果類方法在其所屬類的派生類上呼叫,則該派生類物件會被作為隱含的第一個引數被傳入。

類方法與 C++ 或 Java 中的靜態方法不同。 如果你需要後者,請參閱本節中的 staticmethod()

@staticmethod

將方法轉換為靜態方法。

靜態方法不會接收隱式的第一個引數。要宣告一個靜態方法,請使用此語法

class C:
    @staticmethod
    def f(arg1, arg2, ...): ...

@staticmethod 這樣的形式稱為函式的 decorator

靜態方法的呼叫可以在類上進行 (例如 C.f()) 也可以在例項上進行 (例如 C().f())。

Python中的靜態方法與Java或C ++中的靜態方法類似。另請參閱 classmethod() ,用於建立備用類建構函式的變體。

像所有裝飾器一樣,也可以像常規函式一樣呼叫 staticmethod ,並對其結果執行某些操作。比如某些情況下需要從類主體引用函式並且您希望避免自動轉換為例項方法。對於這些情況,請使用此語法:

class C:
    builtin_open = staticmethod(open)

相關文章