Python基礎——@staticmethod與@classmethod

Inside_Zhang發表於2015-11-27
  • @staticmethod與隱式的靜態成員方法的區別在於是否允許例項物件呼叫該靜態方法(後者是不允許的)

  • @staticmethod與@classmethod的區別在於後者無論是被例項呼叫還是被類物件呼叫傳遞進來的第一個引數永遠是類物件(class object)

@staticmethod的用法

使用@staticmethod宣告的成員函式具有C++類的靜態成員函式的相同的用法,既可以被物件呼叫,更可以被類本身呼叫,因為靜態成員函式屬於類本身。
在python類的定義中,在成員函式的引數列表中如果不指定第一個引數為self(也即c++中的this指標),標識著該方法屬於類的方法,但與@staticmethod的不同之處在於,不可被物件呼叫。

class Dog(object):
    count = 0
    dogs = []
    def __init__(self, name):
        self.name = name
        Dog.count += 1
        Dog.dogs.append(name)
    def bar(self, n):
        print('{} says {}'.format(self.name, 'bar'*n))
    def rollCall(n): # this is a implicitly a class method 
        print('There are {} dog.'.format(Dog.count))
        if n >= Dog.count or n < 0:
            print('They are :')
            for dog in Dog.dogs:
                print(' {}'.format(dog))
        else:
            print('The dog indexed {} is {}'.format(n, Dog.dogs[n]))
if __name__ == '__main__':
    fido = Dog('Fido')
    Dog.rollCall(0)         # 正確
    fido.rollCall(0)        # 拋異常   

如果將rollCall()宣告為@staticmethod,使用例項物件也可呼叫該方法。

@staticmethod與@classmethod的差異

注意區別類物件(class object)例項物件(instance object)

class Kls(object):
    no_inst = 0
    def __init__(self):
        Kls.no_inst += 1
    @classmethod
    def get_no_of_instance(cls_obj):
        return cls_obj.no_inst
ik1 = Kls()
ik2 = Kls()
print(ik1.get_no_of_instance())         # 2
print(Kls.get_no_of_instance())         # 2

使用@classmethod成員函式的一大優勢在於,無論是通過例項物件(instance object,如ik1)還是通過類物件(class object,如Kls)呼叫該型別方法時,傳遞進來的第一個引數總是該類物件(也就是將Kls傳遞給cls_obj)。

相關文章