1. 程式人生 > >self,cls 與 staticmethod,classmethod

self,cls 與 staticmethod,classmethod

一、總體說明

python類的方法有三種(self和cls都可以用別的單詞代替):

  • 一是通過def定義的 普通的一般的,需要至少傳遞一個引數,一般用self,這樣的方法必須通過一個類的例項去訪問,類似於c++中通過物件去訪問;
  • 二是在def前面加上@classmethod,這種類方法的一個特點就是可以通過類名去呼叫,但是也必須傳遞一個引數,一般用cls表示class,表示可以通過類直接呼叫;
  • 三是在def前面加上@staticmethod,這種類方法是靜態的類方法,類似於c++的靜態函式,他的一個特點是引數可以為空,同樣支援類名和物件兩種呼叫方式;

普通的方法,第一個引數需要是self,它表示一個具體的例項本身。 如果用了staticmethod,那麼就可以無視這個self,而將這個方法當成一個普通的函式使用。 而對於classmethod,它的第一個引數不是self,是cls,它表示這個類本身。

三個方法呼叫形式的區別:

例項方法(普通方法)——————————————————————隨著例項屬性的改變而改變

類方法(無論是類呼叫還是例項呼叫)———————————————都是類屬性的值,不隨例項屬性的變化而變化

靜態方法————————————————————————————不可以訪問類屬性,故直接輸出傳入方法的值

栗子:

>>> class A(object):
    def foo1(self):
        print("Hello",self)
    @staticmethod
    def foo2():
        print("hello")
    @classmethod
    def foo3(cls):
        print("hello",cls)

>>> a = A()
>>> a.foo1()          #最常見的呼叫方式,但與下面的方式相同
Hello <__main__.A object at 0x9f6abec>

>>> A.foo1(a)         #這裡傳入例項a,相當於普通方法的self
Hello <__main__.A object at 0x9f6abec>

>>> A.foo2()          #這裡,由於靜態方法沒有引數,故可以不傳東西
hello

>>> A.foo3()          #這裡,由於是類方法,因此,它的第一個引數為類本身。
hello <class '__main__.A'>

>>> A                 #可以看到,直接輸入A,與上面那種呼叫返回同樣的資訊。
<class '__main__.A'>

二、深入理解

self,cls不是關鍵字

栗子:

class A:
    member = "this is a test."

    def __init__(self):
        pass

    @classmethod
    def Print1(cls):
        print("print 1: ", cls.member)

    def Print2(self):
        print("print 2: ", self.member)

    @classmethod
    def Print3(paraTest):
        print("print 3: ", paraTest.member)


a = A()

A.Print1()  # 相當於Print1(A)

a.Print2()  # 相當於Print2(a), 請注意@classmethod

A.Print3()

result:

print 1:  this is a test.
print 2:  this is a test.
print 3:  this is a test.

可以看出來,python在通過“.”呼叫成員函式的時候,會將“.”前面的東西當作函式的第一個引數呼叫。

而且pyhon並不關心我們把類的成員函式的第一個引數的名稱是什麼,我們可以用任意的名稱,可以看Print3的定義就知道了。

|-------------------------------------------------scrat-----------------------------------------------------------|