在講類方法和靜態(tài)方法之前,先來看一個(gè)簡(jiǎn)單的例子:
class A(object):
def foo(self):
print 'Hello ', self
>>> a = A()
>>> a.foo()
Hello, <__main__.A object at 0x10c37a450>
在上面,我們定義了一個(gè)類 A,它有一個(gè)方法 foo,然后我們創(chuàng)建了一個(gè)對(duì)象 a,并調(diào)用方法 foo。
如果我們想通過類來調(diào)用方法,而不是通過實(shí)例,那應(yīng)該怎么辦呢?
Python 提供了 classmethod 裝飾器讓我們實(shí)現(xiàn)上述功能,看下面的例子:
class A(object):
bar = 1
@classmethod
def class_foo(cls):
print 'Hello, ', cls
print cls.bar
>>> A.class_foo() # 直接通過類來調(diào)用方法
Hello, <class '__main__.A'>
1
在上面,我們使用了 classmethod 裝飾方法 class_foo,它就變成了一個(gè)類方法,class_foo 的參數(shù)是 cls,代表類本身,當(dāng)我們使用 A.class_foo() 時(shí),cls 就會(huì)接收 A 作為參數(shù)。另外,被 classmethod 裝飾的方法由于持有 cls 參數(shù),因此我們可以在方法里面調(diào)用類的屬性、方法,比如 cls.bar。
在類中往往有一些方法跟類有關(guān)系,但是又不會(huì)改變類和實(shí)例狀態(tài)的方法,這種方法是靜態(tài)方法,我們使用 staticmethod 來裝飾,比如下面的例子:
class A(object):
bar = 1
@staticmethod
def static_foo():
print 'Hello, ', A.bar
>>> a = A()
>>> a.static_foo()
Hello, 1
>>> A.static_foo()
Hello, 1
可以看到,靜態(tài)方法沒有 self 和 cls 參數(shù),可以把它看成是一個(gè)普通的函數(shù),我們當(dāng)然可以把它寫到類外面,但這是不推薦的,因?yàn)檫@不利于代碼的組織和命名空間的整潔。
@classmethod 裝飾器,可以使用類(也可使用實(shí)例)來調(diào)用方法。@staticmethod 裝飾器,它是跟類有關(guān)系但在運(yùn)行時(shí)又不需要實(shí)例和類參與的方法,可以使用類和實(shí)例來調(diào)用。