Fluent Python -- Python Data Model

什么是 Python Data Model?

Python Data Model 為自定義的數(shù)據(jù)類型(通過 Class)提供與 Python 內(nèi)建類型一致的接口。
實(shí)現(xiàn)方法是:在類中定義一些特殊的方法,比如 __add__() ;當(dāng)開發(fā)者調(diào)用 len(object) 時(shí),python 解析器將執(zhí)行 object.__len__()

作用:使所有 Python 對(duì)象擁有一致的接口浓利。
實(shí)現(xiàn):通過特殊的語法 調(diào)用 對(duì)象中的特殊方法
例子:object[key] --> object.__getitem__(key)

__getitem__, __len__

目標(biāo):實(shí)現(xiàn)類的 __getitem__()__len__() 方法

Python 特性補(bǔ)充

collections.namedtuple:可用于創(chuàng)建沒有方法的對(duì)象

>>> import collections

# 坐標(biāo)軸上的一點(diǎn)
>>> Point = collections.namedtuple('Point', ['x', 'y'])

>>> p1 = Point(5, 10)
>>> p2 = Point(x=50, y=100)

>>> repr(p1)
'Point(x=5, y=10)'

# 訪問元組中的項(xiàng)
# 通過項(xiàng)名
>>> p1.x
5
>>> p1.y
10

# 通過索引
>>> p1[0]
5
>>> p1[1]
10

# 解包
>>> x, y = p1
>>> x
5
>>> y
10

>>> p1
Point(x=5, y=10)
namedtuple
# 根據(jù)字符串創(chuàng)建列表
>>> list("ABC")
['A', 'B', 'C']

>>> 'A B C'.split()
['A', 'B', 'C']

# 列表相加
>>> [1, 2, 3]+list("ABC")
[1, 2, 3, 'A', 'B', 'C']
例子:撲克牌

import collections

class FrenchDeck:
    '''一副撲克牌'''

    # 一張撲克牌
    # rank: 號(hào)碼
    # suit: 花色
    Card = collections.namedtuple('Card', ['suit', 'rank'])

    suits = 'spades diamonds clubs hearts'.split()
    ranks = [i for i in range(2, 11)] + list('JQKA')

    def __init__(self):
        self._card = [self.Card(suit, rank)  for suit in self.suits
                                        for rank in self.ranks]

    def __len__(self):
        '''卡牌的數(shù)量(數(shù)組的長(zhǎng)度'''
        return len(self._card)

    def __getitem__(self, positon):
        '''獲取一張卡牌(數(shù)組中的一個(gè)元素)
            * 支持索引
            * 支持切分
            * 支持迭代
        '''
        return self._card[positon]

In [1]: import Poker

In [3]: poker = Poker.FrenchDeck()

In [4]: len(poker)
Out[4]: 52

In [5]: poker[1]
Out[5]: Card(suit='spades', rank=3)

In [6]: poker[0]
Out[6]: Card(suit='spades', rank=2)

# 前3張牌
In [11]: poker[:3]
Out[11]:
[Card(suit='spades', rank=2),
 Card(suit='spades', rank=3),
 Card(suit='spades', rank=4)]

# 隨機(jī)選取一張撲克牌
In [8]: import random

In [10]: random.choice(poker)
Out[10]: Card(suit='diamonds', rank='Q')

好處

  • 擁有和 Python 內(nèi)建類型一致的 API (len
  • 獲得 Python 特性:切片,迭代
  • 獲得 Python 標(biāo)準(zhǔn)庫支持:reversed, sorted, random.choice

注意

  • 自己不要使用 __foo__ 的變量名钞速,它們使保留給這些特殊方法/變量使用的
  • 除了 直接調(diào)用父類的 __init__ 方法外贷掖,一般不直接調(diào)用這些特殊的方法,而是使用 len foo[0]

模擬數(shù)值計(jì)算

  • + : __add__
  • * : __mul__
  • abs(): __abs__

當(dāng)穿給 __add__ 的兩個(gè)參數(shù)的類型不同時(shí)渴语,其順序要符合定義時(shí)的順序苹威;
或者可以使用 __radd__ 方法

布爾運(yùn)算

bool(objct) 返回 True 或 False

當(dāng)調(diào)用 bool() 時(shí):

  • python 解析器嘗試調(diào)用對(duì)象的 __bool__ 方法
  • __bool__ 未定義時(shí),參數(shù)調(diào)用 __len__ 方法:0 為 False驾凶,其他為 True
  • 如果 __bool____len__ 都為定義牙甫,對(duì)象將永遠(yuǎn)被視為 True

字符串帶表

  • __repr__ : 用于 debug,代表一個(gè)對(duì)象调违。應(yīng)盡可能地還原構(gòu)造對(duì)象的樣子窟哺,比如 Point(1, 2)
  • __str__:用于展示給用戶看,執(zhí)行 print(object) 時(shí)調(diào)用此方法翰萨;若未實(shí)現(xiàn)該方法,會(huì)調(diào)用 __repr__
  • 如果只實(shí)現(xiàn)一個(gè)方法糕殉,選擇 __repr__
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末亩鬼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子阿蝶,更是在濱河造成了極大的恐慌雳锋,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件羡洁,死亡現(xiàn)場(chǎng)離奇詭異玷过,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門辛蚊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粤蝎,“玉大人,你說我怎么就攤上這事袋马〕跖欤” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵虑凛,是天一觀的道長(zhǎng)碑宴。 經(jīng)常有香客問我,道長(zhǎng)桑谍,這世上最難降的妖魔是什么延柠? 我笑而不...
    開封第一講書人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮锣披,結(jié)果婚禮上贞间,老公的妹妹穿的比我還像新娘。我一直安慰自己盈罐,他們只是感情好榜跌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盅粪,像睡著了一般钓葫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上票顾,一...
    開封第一講書人閱讀 51,554評(píng)論 1 305
  • 那天础浮,我揣著相機(jī)與錄音,去河邊找鬼奠骄。 笑死豆同,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的含鳞。 我是一名探鬼主播影锈,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蝉绷!你這毒婦竟也來了鸭廷?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤熔吗,失蹤者是張志新(化名)和其女友劉穎辆床,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體桅狠,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡讼载,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年轿秧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咨堤。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡菇篡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出吱型,到底是詐尸還是另有隱情逸贾,我是刑警寧澤,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布津滞,位于F島的核電站铝侵,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏触徐。R本人自食惡果不足惜咪鲜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撞鹉。 院中可真熱鬧疟丙,春花似錦、人聲如沸鸟雏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽孝鹊。三九已至炊琉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間又活,已是汗流浹背苔咪。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柳骄,地道東北人团赏。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耐薯,于是被迫代替她去往敵國和親舔清。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容