<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>

          【Python基礎(chǔ)】Python 面向?qū)ο缶幊?下篇)

          共 1639字,需瀏覽 4分鐘

           ·

          2020-08-09 09:53

          已完成專題

          1我的施工計(jì)劃

          2數(shù)字專題

          3字符串專題

          4列表專題

          5流程控制專題

          6編程風(fēng)格專題

          7函數(shù)使用

          8.面向?qū)ο缶幊?上篇)

          上一篇面向?qū)ο缶幊?上篇)討論了面向?qū)ο缶幊痰幕A(chǔ)部分,使用案例講解了三大特性:封裝、繼承、多態(tài)。

          今天繼續(xù)討論面向?qū)ο缶幊痰倪M(jìn)階部分

          進(jìn)階專題

          1 創(chuàng)建抽象方法

          上篇講解多態(tài)部分,定義了基類模塊animals2.py,它里面有一個(gè)方法getSpeedBehavior,然后2個(gè)繼承類中分別重寫了此方法。雖然這種模式并不會報(bào)錯(cuò),但卻不是最佳編程寫法。

          class?Animal():
          ???cprop?=?"我是類上的屬性cprop"
          ???
          ???def?__init__(self,name,speed):
          ???????self.name?=?name?#?動(dòng)物名字
          ???????self._speed?=?speed?#?動(dòng)物行走或飛行速度
          ??
          ???def?__str__(self):
          ????????return?'''Animal({0.name},{0._speed})?is?printed
          ????????????????name={0.name}
          ????????????????speed={0._speed}'''
          .format(self)

          ???def?getSpeedBehavior(self):
          ???????pass?

          更加優(yōu)秀的做法,顯示的定義基類的此方法為抽象方法,并且明確指名這兩個(gè)繼承類需要重寫此方法。

          借助Python內(nèi)置的abc模塊,使用abstractmethod裝飾器,Animal類的改進(jìn)版:

          import?abc

          class?Animal():
          ???cprop?=?"我是類上的屬性cprop"
          ???
          ???def?__init__(self,name,speed):
          ???????self.name?=?name?#?動(dòng)物名字
          ???????self._speed?=?speed?#?動(dòng)物行走或飛行速度
          ??
          ???def?__str__(self):
          ????????return?'''Animal({0.name},{0._speed})?is?printed
          ????????????????name={0.name}
          ????????????????speed={0._speed}'''
          .format(self)
          ???
          ???#?使用abstractmethod裝飾器后,變?yōu)槌橄蠓椒?/span>
          [email protected]
          ???def?getSpeedBehavior(self):
          ???????pass

          其他類都不改變。以上就是創(chuàng)建抽象類的方法。

          2 檢查屬性取值

          已經(jīng)在Animal類中定義2個(gè)屬性name和_speed:

          class?Animal():
          ???cprop?=?"我是類上的屬性cprop"
          ???
          ???def?__init__(self,name,speed):
          ???????self.name?=?name?#?動(dòng)物名字
          ???????self._speed?=?speed?#?動(dòng)物行走或飛行速度

          像這種方法定義的屬性,外界可以對屬性賦任意值,這不是合理的。如下speed參數(shù)被賦值為負(fù)值,這肯定不合理:

          jiafeimao?=?Cat('jiafeimao',-2,'gray','CatGenre')

          所以一種解決方法便是使用@property,寫法也很簡潔:

          ???#?讀
          ???@property?
          ???def?_speed(self):
          ???????return?self.__speed
          ??#?寫
          ???@_speed.setter
          ???def?_speed(self,val):
          ???????if?val?0:
          ???????????raise?ValueError('speed?value?is?negative')
          ???????self.__speed?=?val

          Cat('jiafeimao',-2,'gray','CatGenre')執(zhí)行時(shí),會進(jìn)入到@_speed.setter,檢查不滿足,拋出取值異常。

          @property就是給_speed函數(shù)增加功能后返回一個(gè)更強(qiáng)大的函數(shù),@屬性.setter也是一個(gè)函數(shù),裝飾后控制著屬性的寫入操作。

          3 給類添加屬性

          基礎(chǔ)篇說到為實(shí)例添加屬性,只對此實(shí)例生效,其他屬性還是沒有此屬性。怎樣在外面一次添加屬性后,所有實(shí)例都能具有呢。

          答案是為類添加屬性,如下所示,為Cat類增加屬性age后,jiafeimao實(shí)例 和jiqimao實(shí)例都有了age屬性,且都可被修改:

          if?__name__?==?"__main__":
          ????jiafeimao?=?Cat('jiafeimao',2,'gray','CatGenre')
          ????
          ????Cat.age?=?1
          ????jiafeimao.age?=?3
          ????print(jiafeimao.age)?#?3?
          ????jiqimao?=?Cat('jiqimao',3,'dark','CatGenre')
          ????jiqimao.age?=?5
          ????print(jiqimao.age)?#?5

          這就說明,一次為類添加一個(gè)屬性,類的所有實(shí)例都會有這個(gè)新增的屬性。

          這種雖然寫法便利,但是會帶來副作用,支持動(dòng)態(tài)添加實(shí)際上破壞了類的封裝性,為維護(hù)程序帶來不便。同時(shí),如果泛濫使用,屬性過多占用內(nèi)存就會變大,影響程序的性能。

          4 控制隨意添加屬性

          Python應(yīng)該意識到上面動(dòng)態(tài)添加屬性帶來的副作用,因此留出一個(gè)系統(tǒng)魔法函數(shù)__slots__,以此來控制隨意在外添加屬性。

          使用__slots__,定義這個(gè)類只能有哪些屬性,不在這個(gè)元組里的屬性添加都會失敗。

          如下這樣做后,控制Student類只能有屬性name和age,不允許添加其他屬性:

          class?Student(object):
          ????__slots__?=?('name',?'age')?#?用tuple定義允許綁定的屬性名稱

          ????def?__init__(self,name,age):
          ????????self.name?=?name
          ????????self.age?=?age


          s?=?Student('xiaoming',100)?#?創(chuàng)建新的實(shí)例
          s.score=10

          如下異常:

          5 鏈?zhǔn)秸{(diào)用

          每個(gè)對外公開的方法,都返回self,這樣在外面調(diào)用時(shí),便能形成一條鏈?zhǔn)秸{(diào)用線,在pyecharts等框架中可以看到這種調(diào)用風(fēng)格。

          class?Student(object):
          ????__slots__?=?('name',?'age')?#?用tuple定義允許綁定的屬性名稱

          ????def?__init__(self,name,age):
          ????????self.name?=?name
          ????????self.age?=?age
          ????
          ????def?set_name(self,val):
          ????????self.name?=?val?
          ????????return?self?
          ????
          ????def?set_age(self,age):
          ????????self.age?=?age?
          ????????return?self
          ????
          ????def?print_info(self):
          ????????print("name:?"+self.name)
          ????????print("age:?"+?str(self.age))
          ????????return?self
          ?
          s?=?Student('xiaoming',100)?#?創(chuàng)建新的實(shí)例

          (
          ????s
          ????.set_name('xiaoming1')
          ????.set_age(25)
          ????.print_info()
          )

          關(guān)于面向?qū)ο缶幊痰倪M(jìn)階部分,還有一個(gè)重要的設(shè)計(jì)原則:MixIn 原則,這個(gè)我們放到后面在講設(shè)計(jì)模式時(shí)一起討論。

          以上就是面向?qū)ο缶幊痰倪M(jìn)階部分,原創(chuàng)不易,歡迎三連支持


          往期精彩回顧





          獲取一折本站知識星球優(yōu)惠券,復(fù)制鏈接直接打開:

          https://t.zsxq.com/662nyZF

          本站qq群1003271085。

          加入微信群請掃碼進(jìn)群(如果是博士或者準(zhǔn)備讀博士請說明):

          瀏覽 28
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          <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>
                  波多野结衣网站 | A片网电影在线观看 | 亚洲欧美在线电影 | 偷偷操不一样的久久 | 麻豆传媒一区二区在线观看 |