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)