第二章 與Python的無(wú)縫集成----基本特殊方法.

第二章 與Python的悟性陳繼承----基本特殊方法.

python中有有一些特殊的方法,它們?cè)试S我們的類和python更好的集成

  • __repr__():
  • __str__()
  • __format__()
  • __hash__()
  • __bool__()
  • __bytes__()
  • __lt__()
  • __le__()
  • __eq__()
  • __ne__()
  • __gt__()
  • __ge__()
  • __new__()
  • __del__()

2.1 __repr__()__str__()方法

  • 通常str()方法表示的對(duì)象對(duì)用戶更加友好.這個(gè)方法是有對(duì)象的__str__()方法實(shí)現(xiàn)的.

什么時(shí)候重寫 __str__()__repr__()

  • 非集合對(duì)象: 一個(gè)不包括其他集合對(duì)象的'簡(jiǎn)單'對(duì)象,這類對(duì)象格式通常不會(huì)特別復(fù)雜
  • 集合對(duì)象:一個(gè)包括集合的對(duì)象,這類對(duì)象的格式化會(huì)非常復(fù)雜.
非集合對(duì)象的__repr__()__str__()

問(wèn)題1: 什么是集合?

class Card(object):
    def __init__(self, rank, suit):
        self.suit = suit
        self.rank = rank
        self.hard, self.soft = self._points()

    def __repr__(self):
        return '{__class__.__name__}(suit = {suit!r} , rank = {rank!r})'.format(
            __class__=self.__class__, **self.__dict__
        )

    def __str__(self):
        return '{rank}{suit}'.format(**self.__dict__)


class NumberCard(Card):
    def _points(self):
        return int(self.rank), int(self.rank)


x = NumberCard('2', '?')
# 注意下面是重寫后的
print(str(x))  # 2? 
print(x)       # 2?
print(repr(x)) # NumberCard(suit = '?' , rank = '2')
__format__()方法

注意:‘{0!r}'.format()'{0!s}'.format()并不會(huì)調(diào)用__format__()方法,它們會(huì)調(diào)用__repr__()或者__str__().

__hash__()方法

內(nèi)置hash()函數(shù)調(diào)用了__hash__()方法.哈希是一種將復(fù)雜的值簡(jiǎn)化為小整數(shù)的計(jì)算方式.

python有兩個(gè)哈希庫(kù):

  • hashlib
  • zip 有兩個(gè)搞笑的哈希函數(shù)adler32()crc32()
    hasd()函數(shù)主要被用來(lái)創(chuàng)建set,forzenset,dict這些集合類的鍵.這些集合利用了不可變對(duì)象的哈希值來(lái)高效的查找集合中的對(duì)象
決定hash的對(duì)象

并非每個(gè)對(duì)象都需要提供一個(gè)哈希值,尤其是,當(dāng)我們創(chuàng)建一個(gè)包含有狀態(tài),可改變對(duì)象的類時(shí).這類不應(yīng)該返回哈希值,__hash__的定義 應(yīng)該是None

等價(jià)比較有三個(gè)層次:

  • 哈希值相等:意味著兩個(gè)結(jié)果可能相等.哈希值是判斷兩個(gè)對(duì)象有可能相等的快捷方式,如果哈希值不同,兩個(gè)對(duì)象不可能相等,也不可能是同一個(gè)對(duì)象.
  • 比較結(jié)果相等:意味著兩個(gè)對(duì)象的哈希值已經(jīng)是相等的尤仍,這個(gè)比較用的是==運(yùn)算符.如果結(jié)果相等,那么兩個(gè)對(duì)象的有可能是同一個(gè).
  • IDD 相等:這意味著兩個(gè)對(duì)象是同一個(gè)對(duì)象,它們的哈希值仙童,并且使用==的比較結(jié)果相等,這個(gè)比較是用的是is運(yùn)算符.

**基本哈希法(Fundametal Law of Hash):比較相等的對(duì)象的哈希值一定相等.

有關(guān)不可變對(duì)象和繼承的默認(rèn)行為
class Card(object):
    def __init__(self, rank, suit, hard, soft):
        self.suit = suit
        self.rank = rank
        self.hard = hard
        self.soft = soft

    def __repr__(self):
        return '{__class__.__name__}(suit = {suit!r} , rank = {rank!r})'.format(
            __class__=self.__class__, **self.__dict__
        )

    def __str__(self):
        return '{rank}{suit}'.format(**self.__dict__)


class NumberCard(Card):
    def __init__(self, rank, suit):
        super().__init__(str(rank), suit, rank, rank)


class AceCard(Card):
    def __init__(self, rank, suit):
        super(AceCard, self).__init__("A", suit, 1, 11)


class FaceCard(Card):
    def __init__(self, rank, suit):
        super(FaceCard, self).__init__({11: 'J',
                                        12: 'Q',
                                        13: 'K'}[rank], suit, 10, 10)



c1 = AceCard(1,'?')
c2 = AceCard(1,'?')
print(id(c1),id(c2)) # 52067024 52067120 

id()值不同意味著是不同的對(duì)象.
**is測(cè)試基于id()的值,哈希值根據(jù)id()值來(lái)計(jì)算的`

重載不可變對(duì)象

下面是一個(gè)重載了__hash__()__eq__()定義的簡(jiǎn)單類.

class Card2(object):
    def __init__(self, rank, suit, hard, soft):
        self.suit = suit
        self.rank = rank
        self.hard = hard
        self.soft = soft

    def __repr__(self):
        return '{__class__.__name__}(suit = {suit!r} , rank = {rank!r})'.format(
            __class__=self.__class__, **self.__dict__
        )

    def __str__(self):
        return '{rank}{suit}'.format(**self.__dict__)

    def __eq__(self, other):
        return self.suit == other.suit and self.rank == other.rank

    def __hash__(self):
        return hash(self.suit) ^ hash(self.rank)


class AceCard2(Card2):
    insure = True

    def __init__(self, rank, suit):
        super().__init__("A", suit, 1, 11)


c1 = AceCard2(1, '?')
c2 = AceCard2(1, '?')

print(id(c1), id(c2))     # id 是不相同的
print(c1 is c2)           # False
print(hash(c1), hash(c2)) # hash是相同的
print(c1 == c2)           # True
print(set([c1,c2]))       # {AceCard2(suit = '?' , rank = 'A')}
重載可變對(duì)象

下面的類層級(jí)結(jié)構(gòu)中,我們沖在了可變對(duì)象的 __hash__()__eq__()

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末播掷,一起剝皮案震驚了整個(gè)濱河市赂韵,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌倍奢,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異介衔,居然都是意外死亡宏粤,警方通過(guò)查閱死者的電腦和手機(jī)脚翘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)绍哎,“玉大人来农,你說(shuō)我怎么就攤上這事〕缪撸” “怎么了沃于?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)海诲。 經(jīng)常有香客問(wèn)我繁莹,道長(zhǎng),這世上最難降的妖魔是什么特幔? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任咨演,我火速辦了婚禮,結(jié)果婚禮上蚯斯,老公的妹妹穿的比我還像新娘薄风。我一直安慰自己,他們只是感情好拍嵌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布遭赂。 她就那樣靜靜地躺著,像睡著了一般横辆。 火紅的嫁衣襯著肌膚如雪撇他。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,443評(píng)論 1 302
  • 那天龄糊,我揣著相機(jī)與錄音逆粹,去河邊找鬼。 笑死炫惩,一個(gè)胖子當(dāng)著我的面吹牛僻弹,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播他嚷,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼蹋绽,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼芭毙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起卸耘,我...
    開(kāi)封第一講書(shū)人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤退敦,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蚣抗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體侈百,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年翰铡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钝域。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡锭魔,死狀恐怖例证,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情迷捧,我是刑警寧澤织咧,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站漠秋,受9級(jí)特大地震影響笙蒙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜膛堤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一手趣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肥荔,春花似錦、人聲如沸朝群。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)姜胖。三九已至誉帅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間右莱,已是汗流浹背蚜锨。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留慢蜓,地道東北人亚再。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像晨抡,于是被迫代替她去往敵國(guó)和親氛悬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子则剃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

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

  • Python內(nèi)置函數(shù)詳解——總結(jié)篇 ** 引 言** ** 數(shù)學(xué)運(yùn)算** abs:求數(shù)值的絕對(duì)值>>> abs...
    yutiansut閱讀 736評(píng)論 0 1
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法如捅,內(nèi)部類的語(yǔ)法棍现,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法镜遣,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,631評(píng)論 18 399
  • 黑暗孕育了光明己肮,而光明卻背棄了黑暗,黑暗只有孤身一人悲关,而光明卻擁有眾多朋友谎僻,這就是你們向往的光明,崇尚的光明坚洽,你們...
    鞠安ojbk閱讀 373評(píng)論 5 2
  • 其實(shí)我也不知道叫這個(gè)題目對(duì)不對(duì)戈稿,符合不符合我想說(shuō)的事 下午去爬山,天氣突然晴轉(zhuǎn)陰讶舰,伴隨打雷閃電鞍盗,到半山腰就開(kāi)始往回...
    丸子_34c8閱讀 393評(píng)論 0 3
  • 女性般甲,到了大學(xué)會(huì)有很多的改變,大多數(shù)是驚嘆于容貌的徹頭徹尾的“革命”鹅颊,在這個(gè)靠顏值的社會(huì)敷存,似乎誰(shuí)再不注重自己的外在...
    子晨恩閱讀 270評(píng)論 4 3