<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          輕松學(xué)會python面向?qū)ο蟮?0篇---方法屬于類,屬性屬于對象

          共 2467字,需瀏覽 5分鐘

           ·

          2021-03-25 16:26

          方法屬于類,屬性屬于對象,這并不是一個完全正確的論斷,然而,我還是建議你記住它,理解它,因為以此為起點,可以更好的理解類與對象之間的關(guān)系。

          1. 方法屬于類

          如何理解這句話呢,方法的存在,不依賴于對象,而是依賴于類;屬性的存在,不依賴于類,而是依賴于對象。

          class Dog():
          def __init__(self, name):
          self.name = name

          def biting(self):
          print(f'{self.name}在咬人')

          def biting_ex(self):
          print('咬人')

          這是一段簡單的代碼,定義了一個Dog類,先來理解方法屬于類,我增加一行代碼

          Dog.biting_ex(None)

          這行代碼可以正確運行,我傳入?yún)?shù)是None,你可以傳入任意參數(shù),都不是問題。我沒有創(chuàng)建任何實例對象,但是我可以調(diào)用實例方法。

          2. 屬性屬于對象

          biting也可以這樣調(diào)用么,我們來試一下

          Dog.biting(None)

          結(jié)果報錯了

          AttributeError: 'NoneType' object has no attribute 'name'

          None沒有name屬性,屬性依附于對象而存在,沒有創(chuàng)建對象,也就沒有name屬性,修改一下代碼

          dog = Dog('小黑')
          Dog.biting(dog)

          這樣就沒問題了,Dog.biting(dog) 等價于dog.biting()。我創(chuàng)建了一個對象,name屬性也就存在了,更抽象的說法是在內(nèi)存中創(chuàng)建了一個dog對象,dog對象里有一個name屬性,沒有創(chuàng)建對象dog之前,name屬性自然也就不存在。

          3. dog.biting與Dog.biting是同一個東西么

          接下來要講解的,屬于比較深入的內(nèi)容,如果感到吃力,可以放棄

          我們通過查看他們的id來判斷他們是否是同一個東西。

          dog = Dog('小黑')
          print(id(dog.biting))
          print(id(Dog.biting))

          輸出結(jié)果是

          1747144415176
          1747147189376

          竟然不是同一個東西,那對象dog的biting究竟從哪里來的呢?前面不是剛說過方法是屬于類的么,那么按理說,對象所使用的方法應(yīng)該就是類的方法。

          這里的確是一個疑點,所以,我們要深入挖掘。

          3.1 多個對象的biting一樣么

          我再創(chuàng)建出一個對象,看看多個對象的biting是不是同一個東西

          dog = Dog('小黑')
          dog1 = Dog('嘿嘿')
          print(id(dog.biting)) # 1610069776328
          print(id(dog1.biting)) # 1610069776328

          不論創(chuàng)建多少個對象,他們的biting方法的內(nèi)存地址都是相同的,那么他們從哪里來的呢,跟Dog.biting到底有沒有關(guān)系呢,答案是有關(guān)系

          3.2 bound method

          dog = Dog('小黑')
          print(dog.biting)

          注意看輸出結(jié)果

          <bound method Dog.biting of <__main__.Dog object at 0x00000245E1C3BD30>>

          dog.biting 是Dog.biting函數(shù)的綁定方法,雖然不是很容易理解,但是可以明確,他們之間是存在關(guān)系的。

          print(dog.__dict__)
          print(Dog.__dict__)

          我輸出對象dog和類Dog的__dict__, 可以看到,dog的屬性只有name,而類Dog的屬性有很多,包括了biting。這再次印證我們的觀點,方法屬于類,屬性屬于對象。

          結(jié)合bound method 這個描述,我們推斷biting是一個描述器,那么dog.biting 就等價于 Dog.biting.__get__(dog, Dog)),實驗來證明一切

          dog = Dog('小黑')
          print(id(dog.biting)) # 1230893225928
          print(id(Dog.biting.__get__(dog, Dog))) # 1230893225928

          兩次輸出的內(nèi)存地址是一樣的,真想大白于天下。

          3.3 事情的真相

          對象dog并沒有biting屬性,那么在執(zhí)行dog.biting時,對象的__dict__找不到,就要去其類的__dict__中尋找。

          而Dog類中找到的biting是描述器,根據(jù)描述器協(xié)議

          self.descr = descr.__get__(self, obj, type=None) --> value

          因此dog.biting 就等價于 biting.__get__(dog, Dog)),返回的是Dog.biting綁定后的方法,

          如果事情果真如此,那么我可以將biting方法替換掉

          dog = Dog('小黑')

          def too_simple():
          print("驚不驚喜")

          dog.__dict__['biting'] = too_simple
          dog.biting() # 驚不驚喜

          驚不驚喜,意不意外!能在dog.__dict__找到biting,就不會從類里尋找了。

          3.5 繼續(xù)思考

          為什么會是這樣呢?嗯,這樣很合理。

          Dog類只有一個,如果方法屬于對象,那豈不是有多少個對象,就對應(yīng)著有多少個biting方法了么,可這些方法是完全一樣的呀,只需要存在一個就可以了,那么就讓它存在于類中。

          屬性呢?一萬只狗,就應(yīng)該有一萬個名字啊,因此屬性name應(yīng)當是跟隨對象而存在的。


          瀏覽 27
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  成人免费一级黄片 | 亚洲无码伊人 | 精品自拍AV | 国产精品伦子伦免费 | 网红鹿少女演绎点外卖视频 |