python設計模式之內置裝飾器使用(四)


前言

python內部有許多內建裝飾器,它們都有特別的功能,下面對其歸納一下。

系列文章

python自帶裝飾器

staticmethod

staticmethod裝飾器的功能是去除類的方法默認第一個參數是類的實例,使得該方法成為一個普通的函數,staticmethod是一個類,屬於類裝飾器。

class Person(object):
    def eat(self):
        print('eat thing')

    @staticmethod
    def go(): # 不再傳遞self
        print('go')

classmethod

類定義時,除了new方法外,其他定義的方法在調用時第一個參數傳入的必須是一個實例,使用classmethod裝飾器裝飾后,方法的第一個參數是類對象;調用類方法不需要創建類的實例。classmethod也是一個類,所以classmethod是一個類裝飾器。

class Person(object):
    _num_ear = 2

    def eat(self):
        print('eat thing')

    @classmethod
    def go(cls):
        print(cls._num_ear)
        print('go')

if __name__ == '__main__':
    Person.go() # 無需創建實例,直接調用。

property

對於一個類的屬性,python的訪問是沒有限制的,但有時候我們需要對屬性的訪問加以限制,property裝飾器就是干這個的。

property是一個類,它有三個方法,deleter,setter,getter,有兩種使用方式。

class Person(Animal):
    _num_ear = 2

    def __init__(self):
        self._name = 'xiaoming'
        self.age = 20

    def get_name(self):
        print('get name')
        return self._name

    def set_name(self, name):
        print('set name')
        self._name = name

    def delete_name(self):
        print('del name')
        del self._name

    name = property(get_name, set_name, delete_name, doc='name of person')
    # 或使用匿名函數
    name = property(lambda self:self._name, lambda self, name: setattr(self, '_name', name), lambda self:delattr(self,'_name'))

if __name__ == '__main__':
    p = Person()
    print(p.name) # 會調用get_name
    p.name = 'xxxx'  # 會調用set_name
    del p.name     # 會調用delete_name

property可以手動指定限制的函數,有四個參數,但是這樣顯得比較麻煩,可以使用裝飾器的形式。

class Person(Animal):
    _num_ear = 2

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, nm):
        self._name = nm

    @name.deleter
    def name(self):
        del self._name

if __name__ == '__main__':
    p = Person()
    print(p.name) 
    p.name = 'xxxx' 
    del p.name    

一個函數被property裝飾后返回的是property對象,只有fget參數的函數可以被property,因為裝飾器只接受一個參數;另外的屬性設置和刪除需要直觀調用響應的方法。

abstractmethod

python的抽象類和java不一樣,java的抽象類不能實例化,同時抽象方法子類必須實現,否則報錯!但是python抽象類默認是可以實例化的,也可以這樣說,如果我們對抽象類定義:本身不能實例化,子類必須實現抽象方法;那么我們一般寫的基類都不是抽象類。如果想要實現java中的抽象類的效果該怎么辦呢?使用abstractmethod裝飾器,含義是抽象方法。

一個類中的任何方法被abstractmethod裝飾后,這個類不能實例化並且子類必須實現被abstractmethod裝飾的方法。

from abc import abstractmethod,ABCMeta
class Animal(metaclass=ABCMeta):

    @abstractmethod
    def eat(self):
        pass

class Person(Animal):
    _num_ear = 2
    def eat(self):
        print('eat thing')

    @classmethod
    def go(cls):
        print(cls._num_ear)
        print('go')

如果需要定義一個類是抽象類,那么它需要繼承ABCMeta而不是object,這樣abstractmethod裝飾器才會起作用。其起作用的原理是將一個方法的__isabstractmethod__屬性設置為True,這樣解釋器就會檢查子類是否實現了抽象方法。

總結


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM