靜態(tài)方法
是指類中無需實例參與即可調(diào)用的方法(不需要self參數(shù))侮措,在調(diào)用過程中,無需將類實例化乖杠,直接在類之后使用.號運算符調(diào)用方法分扎。
通常情況下,靜態(tài)方法使用@staticmethod裝飾器來聲明胧洒。
示例代碼:
class ClassA(object):
@staticmethod
def func_a():
print('Hello Python')
if __name__ == '__main__':
# 也可以使用實例調(diào)用,但是不會將實例作為參數(shù)傳入靜態(tài)方法
ClassA.func_a()
ca = ClassA()
ca.func_a()</pre>
注意
在Python 2 中畏吓,如果一個類的方法不需要self參數(shù),必須聲明為靜態(tài)方法卫漫,即加上@staticmethod裝飾器菲饼,從而不帶實例調(diào)用它。
而在Python 3中列赎,如果一個類的方法不需要self參數(shù)宏悦,不再需要聲明為靜態(tài)方法,但是這樣的話只能通過類去調(diào)用這個方法包吝,如果使用實例調(diào)用這個方法會引發(fā)異常肛根。
class ClassA(object):
def func_a():
print('Hello Python')
if __name__ == '__main__':
ClassA.func_a()
# 以下使用實例調(diào)用會引發(fā)異常
ca = ClassA()
ca.func_a()
異常信息:
func_a() takes 0 positional arguments but 1 was given
因為func_a沒有聲明為靜態(tài)方法,類實例在調(diào)用func_a時漏策,會隱式地將self參數(shù)傳入func_a派哲,而func_a本身不接受任何參數(shù),從而引發(fā)異常掺喻。
類方法
類方法在Python中使用比較少芭届,類方法傳入的第一個參數(shù)為cls储矩,是類本身。并且褂乍,類方法可以通過類直接調(diào)用持隧,或通過實例直接調(diào)用。但無論哪種調(diào)用方式逃片,最左側(cè)傳入的參數(shù)一定是類本身屡拨。
通常情況下,類方法使用@classmethod裝飾器來聲明
class ClassA(object):
@classmethod
def func_a(cls):
print(type(cls), cls)
if __name__ == '__main__':
ClassA.func_a()
ca = ClassA()
ca.func_a()
從運行結(jié)果可以看出褥实,無論是類調(diào)用還是實例調(diào)用呀狼,類方法都能正常工作。且通過打印cls损离,可以看出cls傳入的都是類實例本身哥艇。
<class 'type'> <class '__main__.ClassA'>
<class 'type'> <class '__main__.ClassA'>
注意
如果存在類的繼承,那類方法獲取的類是類樹上最底層的類僻澎。
class BaseA(object):
@classmethod
def func_a(cls):
print(type(cls), cls)
class BaseB(object):
pass
class ClassA(BaseA, BaseB):
pass
if __name__ == '__main__':
ClassA.func_a()
ca = ClassA()
ca.func_a()
代碼中ClassA繼承自BaseA貌踏、BaseB,在調(diào)用類方法時窟勃,雖然類方法是從BaseA繼承而來祖乳,但是傳入func_a的cls函數(shù)實際上是ClassA,也就是最底層(最具體)的類秉氧。
運行結(jié)果:
<class 'type'> <class '__main__.ClassA'>
<class 'type'> <class '__main__.ClassA'>
所以眷昆,在某些時候,需要明確調(diào)用類屬性時谬运,不要使用類方法傳入的cls參數(shù)隙赁,因為它傳入的是類樹中最底層的類,不一定符合設(shè)計初衷梆暖。
可以直接通過類名訪問類屬性伞访。
class BaseA(object):
@classmethod
def func_a(cls):
# 直接使用類名,而不使用cls
print(BaseA)
print(type(cls), cls)
class BaseB(object):
pass
class ClassA(BaseA, BaseB):
pass
if __name__ == '__main__':
ClassA.func_a()
實例方法
除靜態(tài)方法與類方法外轰驳,類的其他方法都屬于實例方法厚掷。
實例方法需要將類實例化后調(diào)用,如果使用類直接調(diào)用實例方法,需要顯式地將實例作為參數(shù)傳入级解。最左側(cè)傳入的參數(shù)self冒黑,是實例本身。
class ClassA(object):
def func_a(self):
print('Hello Python')
if __name__ == '__main__':
# 使用實例調(diào)用實例方法
ca = ClassA()
ca.func_a()
# 如果使用類直接調(diào)用實例方法,需要顯式地將實例作為參數(shù)傳入
ClassA.func_a(ca)
總結(jié)
相同點:
類方法勤哗、靜態(tài)方法和實例方法都屬于類抡爹,在內(nèi)存中均只保留一份
不通電:
實例可以調(diào)用類方法、靜態(tài)方法芒划、實例方法冬竟,類可以調(diào)用類方法和靜態(tài)方法欧穴。方法調(diào)用者不同,調(diào)用方法時傳入自動傳入的參數(shù)也不相同泵殴。