標籤:好的 line 類方法 style mod nal 編程風格 ack 對象
Python中3種方式定義類方法, 常規方式, @classmethod修飾方式, @staticmethod修飾方式.
class A(object): def foo(self, x): print("executing foo(%s,%s)" % (self, x)) print(‘self:‘, self) @classmethod def class_foo(cls, x): print("executing class_foo(%s,%s)" % (cls, x)) print(‘cls:‘, cls) @staticmethod def static_foo(x): print("executing static_foo(%s)" % x) a = A()1.定義方式
普通的類方法foo()需要通過self參數隱式的傳遞當前類對象的執行個體。 @classmethod修飾的方法class_foo()需要通過cls參數傳遞當前類對象。@staticmethod修飾的方法定義與普通函數是一樣的。
self和cls的區別不是強制的,只是PEP8中一種編程風格,self通常用作執行個體方法的第一參數,cls通常用作類方法的第一參數。即通常用self來傳遞當前類對象的執行個體,cls傳遞當前類對象。
2.綁定對象
foo方法綁定對象A的執行個體,class_foo方法綁定對象A,static_foo沒有參數綁定。
>>> print(a.foo)<bound method A.foo of <__main__.A object at 0x0278B170>>>>> print(a.class_foo)<bound method A.class_foo of <class ‘__main__.A‘>>>>> print(a.static_foo)<function A.static_foo at 0x02780390>
3.調用方式
foo可通過執行個體a調用,類對像A直接調用會參數錯誤。
>>> a.foo(1)executing foo(<__main__.A object at 0x0278B170>,1)self: <__main__.A object at 0x0278B170>>>> A.foo(1)Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: foo() missing 1 required positional argument: ‘x‘
但foo如下方式可以使用正常,顯式的傳遞執行個體參數a。
>>> A.foo(a, 1)executing foo(<__main__.A object at 0x0278B170>,1)self: <__main__.A object at 0x0278B170>
class_foo通過類對象或對象執行個體調用。
>>> A.class_foo(1)executing class_foo(<class ‘__main__.A‘>,1)cls: <class ‘__main__.A‘>>>> a.class_foo(1)executing class_foo(<class ‘__main__.A‘>,1)cls: <class ‘__main__.A‘>
static_foo通過類對象或對象執行個體調用。
>>> A.static_foo(1)executing static_foo(1)>>> a.static_foo(1)executing static_foo(1)
4.繼承與覆蓋普通類函數是一樣的。
class B(A): passb = B()b.foo(1)b.class_foo(1)b.static_foo(1)# executing foo(<__main__.B object at 0x007027D0>,1)# self: <__main__.B object at 0x007027D0># executing class_foo(<class ‘__main__.B‘>,1)# cls: <class ‘__main__.B‘># executing static_foo(1)
問題:@staticmethod修飾的方法函數與普通的類外函數,為什麼不直接使用普通函數?
@staticmethod是把函數嵌入到類中的一種方式,函數就屬於類,同時表明函數不需要訪問這個類。通過子類的繼承覆蓋,能更好的組織代碼。
python中@classmethod @staticmethod區別