欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python筆記001-類的特殊方法

系統(tǒng) 2025 0

Python筆記001-類的特殊方法

以下是我學習《流暢的Python》后的個人筆記,現在拿出來和大家共享,希望能幫到各位Python學習者。

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關注。

本篇主要知識點:

  1. 類的特殊方法(一般都在前后帶有兩個下劃線,比如__len__和__getitem__),其存在的目的是被Python解釋器調用,而不是類的對象來調用。

  2. 對于自定義的類,一般無法體現出Python語言的核心特性,比如迭代和切片等,但是可以通過在自定義類中復寫__len__和__getitem__等特殊方法來實現這些核心功能。對象調用len()方法時實際上Python解釋器調用的是自定義類中的__len__,而對某個對象進行切片獲取元素,或者排序時,Python解釋器調用的是復寫的__getitem__。

  3. 在自定義類中復寫__getitem__至少可以獲得1.類對象的切片和獲取元素,2.對類對象進行迭代,可以是順序迭代也可以是逆序迭代,3.對類對象進行重新排序,4.對類對象進行隨機抽樣等多種功能。

  4. 類的特殊方法有多達100種,作為示例,此處僅僅總結了加減乘除等的復寫方法,并將所有特殊方法都整理成相關表格,便于后續(xù)復寫某些特殊方法時作為參考。

1. 特殊方法示例

這些特殊方法長得比較奇怪,那是因為它提醒用戶,不要輕易調用這些方法,因為它基本上是Python解釋器專用。

比如下面先建立一整副紙牌,它包含有一個屬性_cards,這個一個list,包含有52個Card對象。在復寫了__len__和__getitem__方法之后,就可以直接獲取到這個_cards屬性的總長度和對其進行排序,切片來獲取某幾張紙牌。

            
              
                from
              
               collections 
              
                import
              
               namedtuple
Card
              
                =
              
              namedtuple
              
                (
              
              
                'Card'
              
              
                ,
              
              
                [
              
              
                'rank'
              
              
                ,
              
              
                'suit'
              
              
                ]
              
              
                )
              
              
                # 單張紙牌類
              
              
                class
              
              
                FrenchDeck
              
              
                :
              
              
                # 一副紙牌,包含4種花色,每種13種數字
              
              
    ranks 
              
                =
              
              
                [
              
              
                str
              
              
                (
              
              n
              
                )
              
              
                for
              
               n 
              
                in
              
              
                range
              
              
                (
              
              
                2
              
              
                ,
              
              
                11
              
              
                )
              
              
                ]
              
              
                +
              
              
                list
              
              
                (
              
              
                'JQKA'
              
              
                )
              
              
                # 13種數字
              
              
    suits 
              
                =
              
              
                'spades diamonds clubs hearts'
              
              
                .
              
              split
              
                (
              
              
                )
              
              
                # 四種不同花色:黑桃,方塊,梅花,紅桃
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
        self
              
                .
              
              _cards 
              
                =
              
              
                [
              
              Card
              
                (
              
              rank
              
                ,
              
               suit
              
                )
              
              
                for
              
               suit 
              
                in
              
               self
              
                .
              
              suits
                                        
              
                for
              
               rank 
              
                in
              
               self
              
                .
              
              ranks
              
                ]
              
              
                # _cards屬性是所有紙牌的集合,一個list, 包含4種花色共52張牌
              
              
                def
              
              
                __len__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                # 類FrechDeck的特殊方法:會計算所有紙牌的張數,即52
              
              
                return
              
              
                len
              
              
                (
              
              self
              
                .
              
              _cards
              
                )
              
              
                def
              
              
                __getitem__
              
              
                (
              
              self
              
                ,
              
               position
              
                )
              
              
                :
              
              
                # 類FrechDeck的特殊方法:從52張牌獲取第position張牌
              
              
                return
              
               self
              
                .
              
              _cards
              
                [
              
              position
              
                ]
              
            
          

構建一副紙牌后,我們想知道里面有多少張牌,或者想知道第1張,第10張,最后一張紙牌分別是什么:

            
              
                ## 通過len()獲取deck中一共有多少張牌
              
              
deck
              
                =
              
              FrenchDeck
              
                (
              
              
                )
              
              
                print
              
              
                (
              
              
                len
              
              
                (
              
              deck
              
                )
              
              
                )
              
              
                # 52
              
              
                ## 通過切片方法獲取某個位置的牌
              
              
                print
              
              
                (
              
              deck
              
                [
              
              
                0
              
              
                ]
              
              
                )
              
              
                # Card(rank='2', suit='spades')
              
              
                print
              
              
                (
              
              deck
              
                [
              
              
                10
              
              
                ]
              
              
                )
              
              
                # Card(rank='Q', suit='spades')
              
              
                print
              
              
                (
              
              deck
              
                [
              
              
                -
              
              
                1
              
              
                ]
              
              
                )
              
              
                # Card(rank='A', suit='hearts')
              
            
          

如果沒有復寫__len__函數,在 len(deck) 時會報錯: TypeError: object of type 'FrenchDeck' has no len() .

同理,如果沒有復寫__getitem__方法,在 deck[0] 時報錯: TypeError: 'FrenchDeck' object does not support indexing

可以對deck進行索引來獲取某一個位置的紙牌,那么也就可以通過切片來獲取一個批次,符合一定條件的紙牌,比如下面獲取最后三張牌和牌面全是A的牌。

            
              
                print
              
              
                (
              
              deck
              
                [
              
              
                -
              
              
                3
              
              
                :
              
              
                ]
              
              
                )
              
              
                # 獲取最后三張牌
              
              
                print
              
              
                (
              
              deck
              
                [
              
              
                12
              
              
                :
              
              
                :
              
              
                13
              
              
                ]
              
              
                )
              
              
                # 獲取全是A的牌,間隔型切片
              
            
          

同理,復寫了__getitem__方法后,就可以對deck對象進行迭代,不管是順序迭代還是逆序迭代都可以。

            
              # 順序迭代
for card in deck[:10]:  # 只打印最前面的10張牌
    print(card)

# 逆序迭代
for card in reversed(deck[-10:]):  # 只打印最后面的10張牌
    print(card)

            
          

還可以判斷某張牌是否存在于該副牌內:

            
              
                ## 判斷某張牌是否存在于該副牌內:
              
              
                print
              
              
                (
              
              Card
              
                (
              
              
                'Q'
              
              
                ,
              
              
                'hearts'
              
              
                )
              
              
                in
              
               deck
              
                )
              
              
                # True
              
              
                print
              
              
                (
              
              Card
              
                (
              
              
                'Z'
              
              
                ,
              
              
                'clubs'
              
              
                )
              
              
                in
              
               deck
              
                )
              
              
                # False
              
            
          

有了__getitem__方法,就可以對所有紙牌進行排序操作,此處我們排序的規(guī)定是:梅花2最小,方塊2次之,紅桃2,黑桃2,梅花3.。。這種形式,所以要自定義一個排序方法,這個方法返回一個整數,代表每張牌的大小,那么最小的梅花2就是0,最大的黑桃A就是51。

            
              
                ## 使用自定義方法對所有紙牌進行重新排序
              
              
suit_values 
              
                =
              
              
                dict
              
              
                (
              
              spades
              
                =
              
              
                3
              
              
                ,
              
               hearts
              
                =
              
              
                2
              
              
                ,
              
               diamonds
              
                =
              
              
                1
              
              
                ,
              
               clubs
              
                =
              
              
                0
              
              
                )
              
              
                # 將花色轉換為數值
              
              
                def
              
              
                spades_high
              
              
                (
              
              card
              
                )
              
              
                :
              
              
    rank_value 
              
                =
              
               FrenchDeck
              
                .
              
              ranks
              
                .
              
              index
              
                (
              
              card
              
                .
              
              rank
              
                )
              
              
                # 獲取某張牌的數字
              
              
                return
              
               rank_value 
              
                *
              
              
                len
              
              
                (
              
              suit_values
              
                )
              
              
                +
              
               suit_values
              
                [
              
              card
              
                .
              
              suit
              
                ]
              
              
                # 將某張牌的數字和花色換成整數返回
              
              
                for
              
               card 
              
                in
              
              
                sorted
              
              
                (
              
              deck
              
                ,
              
               key
              
                =
              
              spades_high
              
                )
              
              
                :
              
              
                # 按照自定義方法spades_high得到的整數進行排序
              
              
                print
              
              
                (
              
              card
              
                )
              
            
          

小結一下:自定義類通過復寫__getitem__方法,可以獲得多種原來不存在的功能:比如切片功能,索引功能,還可以判斷某個對象是否存在于類對象列表中,還可以對類對象進行迭代操作和排序操作。

2. 特殊方法的使用

對于自定義的類型,使用這些特殊方法可以使得他們的表現具有某些Python核心功能,在你對這些自定義類型進行操作時,比如 len(deck) 時,Python解釋器會去找deck類的__len__方法。

而Python內置的類型,比如list, str, tuple等,Python解釋器則直接抄近路,會直接返回PyVarObject里的Ob_size屬性,這是一個長度可變的C語言結構體,所以速度要比調用__len__方法快得多。

你自己對這些特殊方法的使用頻率會很低,因為都是Python解釋器自動調用,只有類定義時的__init__方法例外。

2.1 自定義加減乘除功能

            
              
                class
              
              
                Person
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              name
              
                ,
              
              age
              
                ,
              
              score
              
                )
              
              
                :
              
              
        self
              
                .
              
              name
              
                =
              
              name
        self
              
                .
              
              age
              
                =
              
              age
        self
              
                .
              
              score
              
                =
              
              score

    
              
                def
              
              
                __add__
              
              
                (
              
              self
              
                ,
              
              other
              
                )
              
              
                :
              
              
                # 此處僅僅是將得分相加
              
              
                return
              
               self
              
                .
              
              score
              
                +
              
              other
              
                .
              
              score

    
              
                def
              
              
                __sub__
              
              
                (
              
              self
              
                ,
              
              other
              
                )
              
              
                :
              
              
                # 此處將得分相減
              
              
                return
              
               self
              
                .
              
              score
              
                -
              
              other
              
                .
              
              score

    
              
                def
              
              
                __mul__
              
              
                (
              
              self
              
                ,
              
              other
              
                )
              
              
                :
              
              
                # 此處將兩個的年齡相乘
              
              
                return
              
               self
              
                .
              
              age
              
                *
              
              other
              
                .
              
              age

    
              
                def
              
              
                __truediv__
              
              
                (
              
              self
              
                ,
              
              other
              
                )
              
              
                :
              
              
                # 將兩個的得分相除
              
              
                return
              
               self
              
                .
              
              score
              
                /
              
              other
              
                .
              
              score

            
          

這個自定義類Person復寫了加減乘除方法,根據需要對里面的屬性進行算術操作,那么就可以用符號 +,-,*,/ 等進行操作,比如:

            
              P1
              
                =
              
              Person
              
                (
              
              
                'Jack'
              
              
                ,
              
              
                20
              
              
                ,
              
              
                90
              
              
                )
              
              
P2
              
                =
              
              Person
              
                (
              
              
                'Rose'
              
              
                ,
              
              
                18
              
              
                ,
              
              
                60
              
              
                )
              
              
                print
              
              
                (
              
              P1
              
                +
              
              P2
              
                )
              
              
                # 150
              
              
                print
              
              
                (
              
              P1
              
                -
              
              P2
              
                )
              
              
                # 30
              
              
                print
              
              
                (
              
              P1
              
                *
              
              P2
              
                )
              
              
                # 360
              
              
                print
              
              
                (
              
              P1
              
                /
              
              P2
              
                )
              
              
                # 1.5
              
            
          

2.2 自定義print后的形式

還有一個非常常用的特殊函數: __repr__ ,它決定了print被直接調用后結果表現形式。

            
              
                class
              
              
                Person
              
              
                :
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
              name
              
                ,
              
              age
              
                ,
              
              score
              
                )
              
              
                :
              
              
        self
              
                .
              
              name
              
                =
              
              name
        self
              
                .
              
              age
              
                =
              
              age
        self
              
                .
              
              score
              
                =
              
              score
    
              
                def
              
              
                __repr__
              
              
                (
              
              self
              
                )
              
              
                :
              
              
                return
              
              
                'Person(name={},age={},score={})'
              
              
                .
              
              
                format
              
              
                (
              
              self
              
                .
              
              name
              
                ,
              
              self
              
                .
              
              age
              
                ,
              
              self
              
                .
              
              score
              
                )
              
              

P1
              
                =
              
              Person
              
                (
              
              
                'Jack'
              
              
                ,
              
              
                20
              
              
                ,
              
              
                90
              
              
                )
              
              
                print
              
              
                (
              
              P1
              
                )
              
              
                # Person(name=Jack,age=20,score=90)
              
            
          

如果沒有復寫 __repr__ ,在用 print(P1) 時,會得到內存地址信息,人眼無法判斷出具體內容,復寫之后,就可以按照我們想要的形式直接print。

3. 特殊方法匯總

Python內置的特殊方法有將近一百種,其中有很多是實現算數運算,位運算和比較操作的,下面將這些方法的意義總結如下:

下面的整理于:CSDN: Python中特殊方法的分類與總結

所以,如果自定義類想實現某方面的功能,可以參考上面的表格來逐一實現即可。

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關注。

本文所有代碼都已經上傳到我的github,歡迎下載

參考資料:

  1. 《流暢的Python》,Luciano Ramalho (作者) 安道 , 吳珂 (譯者)。

  2. CSDN:Python中特殊方法的分類與總結


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。。?/p>

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久亚洲欧美日韩精品专区 | 日韩视频免费 | 老牛影视av一区二区在线观看 | 色哟哟哟在线精品观看视频 | 五月激情六月 | 欧洲免费无线码二区5 | 国产高清成人 | 欧美四虎影院 | 大片一级| 天天干天天摸 | 国产成人免费视频网站高清观看视频 | 成人午夜亚洲影视在线观看 | 国产精品美女久久久久久久久久久 | 欧美日韩精品一区二区三区 | 国产成人精品一区二区三区四区 | 欧美成人黑人视频免费观看 | 成人免费久久精品国产片久久影院 | 久久精品在这里 | 国产免费小视频在线观看 | 精品国产三级 | 色噜噜狠狠色综合欧洲 | 丝袜捆绑调教视频免费区 | 色天天影视 | 日日a.v拍夜夜添久久免费 | 无码免费人妻A片AAA毛 | 九九热在线免费视频 | 国模论坛 | 久久亚洲国产精品日日av夜夜 | 精品国产污污免费网站 | 韩国福利影院 | 日本又黄又粗暴的gif动态图含羞 | 国产色综合一区二区三区 | 亚洲乱码在线 | 久久综合伊人 | 在线国产一区 | 日干夜干天天干 | 亚洲一区在线日韩在线深爱 | 国产中文字幕一区 | 成人在线视频网 | 欧美日韩在线免费 | 亚洲国产系列 |