Python中的method
通常來說,Python中的類(class)可以包含三類方法:@staticmethod,@classmethod和沒有任何decorator修飾的實例方法。下面我們分別討論這幾種方法之間的區(qū)別。
示例代碼
class A(object):
def func(self, x):
print('executing func with %s, %s.' %(str(self), str(x)))
@classmethod
def class_func(cls, x):
print('executing class_func with %s, %s.' %(str(cls), str(x)))
@staticmethod
def static_func(x):
print('executing statuc_func with %s.' %(str(x))
a = A()
instance method
上面class中的func()就是一個instance method。也就是我們平時最常用的方法。instance method綁定于類的實例,同時instance method隱式接收一個該類的實例作為輸入的第一個參數(shù),同時也只能由該類的實例調(diào)用。
當我們用A類的實例調(diào)用func的時候,實際上func已經(jīng)是一個部分被應用的方法了,或者說func所接收的self參數(shù)實際上已經(jīng)同該實例綁定了。
如下面的例子所示:
>>> a.func(1)
executing func with <__main__.A object at 0x102c1bf90>, 1.
>>> A.func(1)
TypeError: unbound method func() must be called with A instance as first argument (got int instance instead)
# a.func()的self參數(shù)已經(jīng)與a綁定,所以下面的異常顯示1 given.
>>> a.func()
TypeError: func() takes exactly 2 arguments (1 given)
>>> a.func
<bound method A.func of <__main__.A object at 0x102c1bf90>>
class method
所謂的class method,或說類方法,就是指綁定于某一個類的方法,從屬于類而非其實例。Python中的的類方法也就是Java中所謂的類方法或靜態(tài)方法。上面class中的class_func()就是class method。
從語法上看,class method可以由類本身調(diào)用,也可以由類的實例調(diào)用。但由類實例調(diào)用class method從原則上來說違反了class method的本意。所以不推薦使用。
同instance method綁定實例類似,class method所接收的cls參數(shù)同其所屬的類綁定。
如下面例子所示:
>>> A.class_func(1)
executing class_func with <class '__main__.A'>, 1.
>>> a.class_func(1)
executing class_func with <class '__main__.A'>, 1.
# A.class_func的第一個參數(shù)已經(jīng)與A綁定,所以下面的異常顯示1 given.
>>> A.class_func()
TypeError: class_func() takes exactly 2 arguments (1 given)
>>> A.class_func
<bound method type.class_func of <class '__main__.A'>>
static method
static method不與類中的任何元素綁定。static method就如同在python文件中直接定義一個方法一樣,不同之處只在于。同class method和instance method不同的是,static method不接收任何隱式傳入的參數(shù)(比如class method的cls和instance method的self)。static method可以由類本身或類實例調(diào)用。
staticmethod所起的作用主要在于將邏輯上屬于該類的方法放在該類中,從而保存面向?qū)ο蠓庋b的性質(zhì)。
如下面例子所示:
>>> A.static_func(1)
executing statuc_func with 1.
>>> a.static_func(1)
executing statuc_func with 1.
>>> A.static_func
<function __main__.static_func>
class method的使用示例:提供額外的構造器
定義一個類A:
class A(object):
def __init__(self, s):
self.s = s
@classmethod
def construct_from_list(cls, str_list):
a = cls('')
a.s = ','.join(str(ele) for ele in str_list)
return a
def __repr__(self):
print('A(%r)' % (self.s))
return('A.object<{}>'.format(self.s)
然后進行如下操作:
>>> a1 = A('1,2,3')
>>> a1
A('1,2,3')
A.object<1,2,3>
>>> a2 = A.construct_from_list(range(3))
>>> a2
A('0,1,2')
A.object<0,1,2>
可見我們定義的class method可以作為另一個構造器使用。
同時該構造器在子類中仍然可用:
class B(A):
def __repr__(self):
return 'B<{}>'.format(self.s.upper())
然后進行如下操作:
>>> b = B.construct_from_list(['a', 'b']
>>> b
B<A,B>
可見該構造器在子類中任然能夠調(diào)用。