1. 程式人生 > >Python的靜態方法和類方法

Python的靜態方法和類方法

cts -i ack diff 繼承 ssm from 靜態方法 print

Python中使用@staticmethod這個裝飾器讓方法變為靜態方法

一:定義

@staticmethod: 首先它是一個裝飾器,被裝飾的方法不需要隱含的參數,對象和對象的實例都可以調用靜態方法

類方法是通過@classmethod進行裝飾,被裝飾的方法第一個隱含參數是cls,同樣對象和對象的實例都可以調用類方法

這裏還有一個叫實例方法,實例方法就是實例的方法,它是與實例進行綁定的,只能實例進行調用,第一個隱含參數是self

二:舉例說明

翻譯自:https://stackoverflow.com/questions/136097/what-is-the-difference-between-staticmethod-and-classmethod-in-python 高分回答

@staticmethod與@classmethod的區別:

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()

1.下面是實例方法調用函數嗎,實例a被隱式傳遞做為第一個參數,即self

a.foo(1)
# executing foo(<__main__.A object at 0xb7dbef0c>,1)

2.當調用類方法時,實例的類就被隱式傳遞給函數作為第一個參數,即cls

a.class_foo(1)
# executing class_foo(<class ‘__main__.A‘>,1)

你當然也可以使用類調用class.foo,實際上你如果想定義某個函數為類函數,那是因為多半想使用類進行訪問而不是實例,A.foo(1)會

拋出TypeError(實例方法不能類進行調用),但是A.class_foo(1)卻可以正常調用

A.class_foo(1)
# executing class_foo(<class ‘__main__.A‘>,1)

還有一個用法:類方法可以被用來創建可繼承的動態構造器

3.在使用staticmethods時,不需要隱含的第一個函數,靜態函數的行為除了可以類方法和實例方法進行訪問外,和普通方法沒有什麽區別

a.static_foo(1)
# executing static_foo(1)

A.static_foo(hi)
# executing static_foo(hi)

靜態方法常常用於將那些類與類之間有一些相同邏輯的函數進行組合(group functions)

foo只是一個函數,但是當你使用a.foo時你並不是獲取函數,你獲取的是“”第一個參數綁定到實例對象a的部分實現的函數版本“”,foo函數需要連個參數,

但是a.foo只需要一個參數,a綁定到foo函數,這就是下面這個“bound”的意思

print(a.foo)
# <bound method A.foo of <__main__.A object at 0xb7d52f0c>>

類似的,對於類方法,類綁定到foo函數的

print(a.class_foo)
# <bound method type.class_foo of <class ‘__main__.A‘>>

那麽對於靜態函數,就沒有綁定的對象

print(a.static_foo)
# <function static_foo at 0xb7d479cc>

三:類函數可以用於多態

class method綁定到類,而且被子類繼承,子類調用的時候傳入實際調用時的子類型,可以用這個子類型調用其他class method,
這樣就可以在子類型中override某些class method實現多態。static方法一般是不存在override的,它調用的時候沒有綁定到具體的參數,所以也不能靠自己實現多態。

>>> class DictSubclass(dict):
...     def __repr__(self):
...         return "DictSubclass"
... 
>>> dict.fromkeys("abc")
{a: None, c: None, b: None}
>>> DictSubclass.fromkeys("abc")
DictSubclass
>>> 

 

Python的靜態方法和類方法