全部放一個裡面篇幅過大了,就拆分成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中的提示資訊
把一個方法封裝成類方法。
一個類方法把類自己作為第一個實參,就像一個實體方法把範例自己作為第一個實參。請用以下習慣來宣告類方法:
class C:
@classmethod
def f(cls, arg1, arg2): ...
@classmethod
這樣的形式稱為函數的 decorator
類方法的呼叫可以在類上進行 (例如 C.f()
) 也可以在範例上進行 (例如 C().f()
)。 其所屬類以外的類範例會被忽略。 如果類方法在其所屬類的派生類上呼叫,則該派生類物件會被作為隱含的第一個引數被傳入。
類方法與 C++ 或 Java 中的靜態方法不同。 如果你需要後者,請參閱本節中的 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)