Python類的成員

Python類的成員

1、細分類的組成成員

類大體分爲兩大部分:python

  1. 靜態屬性
  2. 動態方法
class A:
    # 靜態屬性部分
    name = "dogfa"
    age = 18
    
    # 動態方法部分
    def __init__(self, name, age):
        self.name = name
        self.age = age

每一個區域詳細劃分又能夠分爲:微信

class A:
    name = "dogfa"  # 靜態屬性
    __age = 18      # 私有靜態屬性

    def __init__(self, name, gender):  # 雙下方法(內置方法)
        self.name = name               # 對象屬性
        self.__gender = gender         # 私有對象屬性

    def __func(self):       # 私有方法
        pass

    def func(self):         # 普通方法
        pass

    @classmethod
    def classfunc(cls):     # 類方法
        pass

    @staticmethod
    def staticfunc():       # 靜態方法
        pass

    @property
    def prop(self):         # 屬性
        pass

2、類的私有成員

對於每個類的成員而言都有兩種形式:函數

  • 公有成員,在任何地方都能訪問
  • 私有成員,只有在類的內部才能方法

私有成員和公有成員的訪問限制不一樣微信支付

靜態屬性設計

  • 公有靜態屬性:類能夠訪問;類內部能夠訪問;派生類中能夠訪問
  • 私有靜態屬性:僅類內部能夠訪問;

對象屬性code

  • 公有對象屬性:對象能夠訪問;類內部能夠訪問;派生類中能夠訪問
  • 私有對象屬性:僅類內部能夠訪問;

方法:orm

  • 公有方法:對象能夠訪問;類內部能夠訪問;派生類中能夠訪問
  • 私有方法:僅類內部能夠訪問;

總結:對於這些私有成員來講,他們只能在類的內部使用,不能再類的外部以及派生類中使用。對象

tips:非要訪問私有成員的話,能夠經過 對象._類__屬性名,可是絕對不容許!!繼承

爲何能夠經過._類__私有成員名訪問呢?由於類在建立時,若是遇到了私有成員它會將其保存在內存時自動在前面加上_類名。接口

3、類的其它成員

這裏的其餘成員主要就是類方法:

方法包括:普通方法、靜態方法和類方法,三種方法在內存中都歸屬於類,區別在於調用方式不一樣。

實例方法

​ 定義:第一個參數必須是實例對象,該參數名通常約定爲「self」,經過它來傳遞實例的屬性和方法(也能夠傳類的屬性和方法);

​ 調用:只能由實例對象調用。

類方法

​ 定義:使用裝飾器@classmethod。第一個參數必須是當前類對象,該參數名通常約定爲「cls」,經過它來傳遞類的屬性和方法(不能傳實例的屬性和方法);

​ 調用:實例對象和類對象均可以調用。

靜態方法

​ 定義:使用裝飾器@staticmethod。參數隨意,沒有「self」和「cls」參數,可是方法體中不能使用類或實例的任何屬性和方法;

​ 調用:實例對象和類對象均可以調用。

雙下方法

 定義:雙下方法是特殊方法,他是解釋器提供的由雙下劃線加方法名加雙下劃線 __方法名__的具備特殊意義的方法,好比__init__

 調用:不一樣的雙下方法有不一樣的觸發方式,就比如盜墓時觸發的機關同樣,不知不覺就觸發了雙下方法,例如:__init__

  1. 類方法

    應用場景:

    1. 類中有些方法是不須要對象參與

      class A:
          name = "dogfa"
          index = 0
      
          @classmethod
          def func(cls):
              return cls.name + str(cls.index)
      
      print(A.func())
    2. 對類中的靜態變量進行改變,要用類方法

      class A:
          name = "dogfa"
          index = 0
      
          @classmethod
          def func(cls, name):
              cls.name = name
              return cls.name
      
      print(A.func("oldniu"))
    3. 繼承中,父類獲得子類的類空間,而後能夠對子類隨心所欲

      class A:
          name = "dogfa"
          index = 0
      
          @classmethod
          def func(cls):
              print(cls)  # 獲取B類的類空間(<class '__main__.B'>)
              cls.name = "djb"    # 給B類添加靜態屬性
      
      class B(A):
          pass
      
      B.func()
      print(B)  # <class '__main__.B'>
      print(B.__dict__) # {'__module__': '__main__', '__doc__': None, name': 'djb'}
  2. 靜態方法

    靜態方法是類中的函數,不須要實例。靜態方法主要是用來存放邏輯性的代碼,邏輯上屬於類,可是和類自己沒有關係,也就是說在靜態方法中,不會涉及到類中的屬性和方法的操做。能夠理解爲,靜態方法是個獨立的、單純的函數,它僅僅託管於某個類的名稱空間中,便於使用和維護。

    import time
    
    class TimeTest(object):
        def __init__(self, hour, minute, second):
            self.hour = hour
            self.minute = minute
            self.second = second
    
        @staticmethod
        def showTime():
            return time.strftime("%H:%M:%S", time.localtime())
    
    print(TimeTest.showTime())   # 12:07:02
    t = TimeTest(2, 10, 10)
    nowTime = t.showTime()
    print(nowTime)              # 12:07:02

    如上,使用了靜態方法(函數),然而方法體中並沒使用(也不能使用)類或實例的屬性(或方法)。若要得到當前時間的字符串時,並不必定須要實例化對象,此時對於靜態方法而言,所在類更像是一種名稱空間。

    其實,咱們也能夠在類外面寫一個一樣的函數來作這些事,可是這樣作就打亂了邏輯關係,也會致使之後代碼維護困難。

  3. 屬性

    屬性 : 將一個方法假裝成一個 屬性,在代碼的級別上沒有本質的提高,可是讓其看起來跟合理。

    什麼是特性property

    property是一種特殊的屬性,訪問它時會執行一段功能(函數)而後返回值

    爲何要用property

    將一個類的函數定義成特性之後,對象再去使用的時候obj.name,根本沒法察覺本身的name是執行了一個函數而後計算出來的,這種特性的使用方式遵循了統一訪問的原則

    class Goods:
    
        def __init__(self, original_price, discount):
            self.original_price = original_price
            self.discount = discount
    
        @property
        def price(self):
            new_price = float(self.original_price) * float(self.discount)
            return new_price
    
        # 修改原價
        @price.setter
        def price(self, value):
            if isinstance(value, int):
                self.original_price = value
            else:
                raise TypeError("{0} must be in int".format(value))
    
        # 刪除原價
        @price.deleter
        def price(self):
            del self.original_price
    
    
    good = Goods(100, 0.8)
    # 獲取商品價格
    print(good.price)        # 80.0
    
    # 修改商品價格
    good.price = 89
    print(good.price)        # 71.2

4、類的約束

抽象類:抽象類是一個介於類和接口之間的一個概念,同時具有類和接口的部分特性,能夠用來實現歸一化設計。

Python中沒有接口類這種東西。

引入抽象類的概念對類進行約束:

from abc import ABCMeta, abstractmethod

class Payment(metaclass=ABCMeta):    # 抽象類 規範和約束  metaclass指定的是一個元類
    @abstractmethod
    def pay(self): pass     # 抽象方法

class WeChatPay(Payment):
    def pay(self, money):
        print("使用微信支付了{0}元".format(money))

class AliPay(Payment):
    def pay(self, money):
        print("使用支付寶支付了{0}元".format(money))

class JdPay(Payment):
    pass
    # def pay(self, money):
        # print("使用京東支付了{0}元".format(money))

def pay(obj, money):
    obj.pay(money)


ali = AliPay()
wechat = WeChatPay()    # 歸一化設計:不論是哪個類的對象,都調用同一個函數去完成類似的功能
jd = JdPay()    # JdPay沒有實現父類中的抽象類pay方法,在實例化對象時會報錯

pay(ali, 300)
pay(wechat, 500)
相關文章
相關標籤/搜索