標籤:day color tput ali 類變數 方法 就會 功能 head
原文地址68957848
原文地址78165645
原文地址https://www.cnblogs.com/1204guo/p/7832167.html
在Python裡, 在class裡定義的方法可以大致分為三類: 執行個體方法, 類方法與靜態方法.
用一個表格總結如下:
方法類型 |
修飾 |
調用者 |
預設首參 |
執行個體方法 |
無 |
instance |
self |
類方法 |
@classmethod |
cls, instance |
cls |
靜態方法 |
@staticmethod |
cls, instance |
無 |
樣本:
class Foo(): # 無修飾 def instance_method(self): #傳入的第一個參數是self, 即instance本身 print(‘the first argument of instance_method:‘, self) @classmethod def class_method(cls): # 傳入的第一個參數是class print(‘the first argument of class_method:‘, cls) @staticmethod def static_method(): # 沒有預設的首位參數, 只有自訂參數 print(‘the first argument of static_method:‘)foo = Foo()foo.instance_method()Foo.class_method()foo.class_method()Foo.static_method()foo.static_method()try: Foo.instance_method()except: print(‘instance method can not be accessed through class.‘)
輸出:
the first argument of instance_method: <__main__.Foo object at 0x7fd135ec3b38>the first argument of class_method: <class ‘__main__.Foo‘>the first argument of class_method: <class ‘__main__.Foo‘>the first argument of static_method:the first argument of static_method:instance method can not be accessed through class
需要注意:
1. @classmethod
與@staticmethod
是Python的built-in methods.
2. 特殊方法__new__
雖然不用@classmethod
修飾, 但它也是class method.
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
classmethod:類方法
staticmethod:靜態方法
在Python中,靜態方法和類方法都是可以通過類對象和類對象執行個體訪問。但是區別是:
@classmethod 是一個函數修飾符,它表示接下來的是一個類方法,而對於平常我們見到的則叫做執行個體方法。 類方法的第一個參數cls,而執行個體方法的第一個參數是self,表示該類的一個執行個體。
普通對象方法至少需要一個self參數,代表類對象執行個體
類方法有類變數cls傳入,從而可以用cls做一些相關的處理。並且有子類繼承時,調用該類方法時,傳入的類變數cls是子類,而非父類。
對於類方法,可以通過類來調用,就像C.f(),有點類似C++中的靜態方法, 也可以通過類的一個執行個體來調用,就像C().f(),這裡C(),寫成這樣之後它就是類的一個執行個體了。
靜態方法則沒有,它基本上跟一個全域函數相同,一般來說用的很少
classmethod必須使用類對象作為第一個參數,而staticmethod則可以不傳遞任何參數。
class Date: def __init__(self,day=0, month=0, year=0): self.day=day self.month = month self.year = year @classmethod def from_string(cls, date_as_string): day, month, year = map(int,date_as_string.split(‘-‘)) my_date = cls(day, month, year) return my_date @staticmethod def is_date_valid(date_as_string): day, month, year = map(int, date_as_string.split(‘-‘)) return day <= 31 and month <= 12 and year <= 3999if __name__ == ‘__main__‘: my_date = Date.from_string(‘11-09-2012‘) print(my_date.day, my_date.month,my_date.year) is_date = Date.is_date_valid(‘13-13-2012‘) print(is_date)outputs: 11 9 2012False
在來看另外的例子,為了驗證有子類繼承時,子類調用該類方法時,傳入的類變數cls是子類,而非父類
class A: @classmethod def cm(cls): print(‘類方法cm(cls)調用者:‘, cls.__name__) @staticmethod def sm(): print(‘靜態方法sm()被調用‘)class B(A): passA.cm() # 類方法cm(cls)調用者: AB.cm() # 類方法cm(cls)調用者: BA.sm() # 靜態方法sm()被調用B.sm() # 靜態方法sm()被調用
下面我們來看為什麼要用到staticmethod與classmethod。
class Kls: def __init__(self,data): self.data = data def printd(self): print(self.data)ik1=Kls(‘arun‘)ik2=Kls(‘seema‘)ik1.printd()ik2.printd()
# 如果現在我們想寫一些僅僅與類互動而不是和執行個體互動的方法會怎麼樣呢? 我們可以在類外面寫一個簡單的方法來做這些,# 但是這樣做就擴散了類代碼的關係到類定義的外面. 如果像下面這樣寫就會導致以後代碼維護的困難:def get_no_of_instances(cls_obj): return cls_obj.no_instclass Kls: no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1ik1 = Kls()ik2 = Kls()print(get_no_of_instances(Kls)) # 2
應用classmethod
class Kls(object): no_inst = 0 def __init__(self): Kls.no_inst = Kls.no_inst + 1 @classmethod def get_no_of_instance(cls_obj): return cls_obj.no_instik1 = Kls()ik2 = Kls()print(ik1.get_no_of_instance())print(Kls.get_no_of_instance())# 2# 2
@staticmethod
經常有一些跟類有關係的功能但在運行時又不需要執行個體和類參與的情況下需要用到靜態方法
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Python的方法主要有3個,即靜態方法(staticmethod),類方法(classmethod)和執行個體方法,如下:
12345678910111213141516 |
def foo(x): print "executing foo(%s)" % (x) class A( object ): def foo( self ,x): print "executing foo(%s,%s)" % ( self ,x) @classmethod def class_foo( cls ,x): print "executing class_foo(%s,%s)" % ( cls ,x) @staticmethod def static_foo(x): print "executing static_foo(%s)" % x a = A() |
這個self和cls是對類或者執行個體的綁定,對於一般的函數來說我們可以這麼調用foo(x)
,這個函數就是最常用的,它的工作跟任何東西(類,執行個體)無關.對於執行個體方法,我們知道在類裡每次定義方法的時候都需要綁定這個執行個體,就是foo(self, x)
,為什麼要這麼做呢?因為執行個體方法的調用離不開執行個體,我們需要把執行個體自己傳給函數,調用的時候是這樣的a.foo(x)
(其實是foo(a, x)
).類方法一樣,只不過它傳遞的是類而不是執行個體,A.class_foo(x)
.注意這裡的self和cls可以替換別的參數,但是python的約定是這倆,還是不要改的好.
對於靜態方法其實和普通的方法一樣,不需要對誰進行綁定,唯一的區別是調用的時候需要使用a.static_foo(x)
或者A.static_foo(x)
來調用.
python中 staticmethod與classmethod