Python魔法方法(持續(xù)更新)

Python魔法方法(持續(xù)更新)

簡(jiǎn)介

魔法方法是python內(nèi)置方法凡涩,不需要主動(dòng)調(diào)用,存在的目的是為了給python的解釋器進(jìn)行調(diào)用疹蛉,幾乎每個(gè)魔法方法都有一個(gè)對(duì)應(yīng)的內(nèi)置函數(shù)活箕,或者運(yùn)算符,當(dāng)我們對(duì)這個(gè)對(duì)象使用這些函數(shù)或者運(yùn)算符時(shí)就會(huì)調(diào)用類中的對(duì)應(yīng)魔法方法可款,可以理解為重寫這些python的內(nèi)置函數(shù)育韩。魔法方法的形式通常是__str__是左右兩個(gè)下劃線通常是在類中

__len__方法

__len__魔法方法是可以使得len()方法使用在對(duì)象上,下面這個(gè)例子是模擬撲克牌

import collections
card = collections.namedtuple('card', ["rank", 'suit'])
class FrenchDeck:
    ranks = [ str(n) for n in range(2, 11)] + list("JQKA")
    suits = 'spades diamonds clubs hearts'.split()

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

    def __len__(self):
        return len(self._cards)
>>> fd = FrenchDeck()
>>> len(fd)  # 可以直接使用len函數(shù)查看fd對(duì)象的長(zhǎng)度
52

namedtuple()方法作用是返回一個(gè)只攜帶屬性的對(duì)象闺鲸,如果你需要一個(gè)對(duì)象筋讨,同時(shí)這個(gè)對(duì)象中只有少量屬性那么可以嘗試使用這個(gè)方法。下面是官方文檔給的例子摸恍,可以通過下標(biāo)的形式取得屬性

>>> # Basic example
>>> Point = namedtuple('Point', ['x', 'y'])
>>> p = Point(11, y=22)     # instantiate with positional or keyword arguments
>>> p[0] + p[1]             # indexable like the plain tuple (11, 22)
33
>>> x, y = p                # unpack like a regular tuple
>>> x, y
(11, 22)
>>> p.x + p.y               # fields also accessible by name
33
>>> p                       # readable __repr__ with a name=value style
Point(x=11, y=22)

__getitem__方法

__getitem__擁有此方法的對(duì)象可以通過的使用列表的形式進(jìn)行對(duì)象操作悉罕,如:切片,下標(biāo)取值

class FrenchDeck:
    ranks = [ str(n) for n in range(2, 11)] + list("JQKA")
    suits = 'spades diamonds clubs hearts'.split()

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

    def __len__(self):
        return len(self._cards)

    def __getitem__(self, item):
        return self._cards[item]
>>> fd[0]
card(rank='2', suit='spades')
>>> fd[0:2]
[card(rank='2', suit='spades'), card(rank='3', suit='spades')]
>>> for i in fd:
            print(i)
card(rank='2', suit='spades')
card(rank='3', suit='spades')
card(rank='4', suit='spades')
card(rank='5', suit='spades')
........

<font color="red">特別注意</font>立镶,雖然可以通過循環(huán)的形式取出對(duì)象中值壁袄,但并不代表它是一個(gè)可迭代對(duì)象,即使你在方法中返回的是字符串也可以循環(huán)媚媒,不過字符串循環(huán)會(huì)一直無限循環(huán)下去嗜逻,直到你手動(dòng)停止。<font color="red">主要原因是欣范,因?yàn)樵谑褂肙bj[key]時(shí)变泄,python解釋器自動(dòng)幫你調(diào)用了__getitem__(self,item)方法,所以只要不使用item這個(gè)參數(shù)恼琼,無論你傳什么參數(shù)都不會(huì)報(bào)錯(cuò)妨蛹,返回什么值是有你決定的</font>

>>> isinstance(fd, collections.Iterable)
False
class A:

    def __getitem__(self, item):
        print("我被調(diào)用了")
        return item
if __name__ == '__main__':
    a = A()
    print(a["aaaa"])
# output 
# 我被調(diào)用了
# aaaa

__abs__方法

__abs__擁有此方法的可以直接使用abs()方法, 下面這個(gè)列子是模擬二維向量

from math import hypot
class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
        
    def __abs__(self):
        # hypot返回x和y的平方和的平方根
        return hypot(self.x, self.y)
>>> abs(Vector(1, 2)) # 返回向量(1, 2)的模
2.23606797749979

__add__方法

擁有此方法的可以使得類的實(shí)例進(jìn)行相加晴竞,類似重載運(yùn)算符

from math import hypot
class Vector:

    def __init__(self, x=0, y=0):
        self.x = x
        self.y = y
        
    def __abs__(self):
        # hypot返回x和y的平方和的平方根
        return hypot(self.x, self.y)
    
    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        return Vector(x, y)
    
    def __repr__(self):
        # 相當(dāng)于java中的toString方法, 稍后會(huì)講這個(gè)方法
        return "Vector(%s, %s)" % (self.x, self.y)
>>> v1 = Vector(1, 2)
>>> v2 = Vector(3, 1)
>>> v1 + v2
Vector(4, 3)

即我可以通過修改類中的__add__方法來重載+運(yùn)算符

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛙卤,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子噩死,更是在濱河造成了極大的恐慌颤难,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件已维,死亡現(xiàn)場(chǎng)離奇詭異行嗤,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)垛耳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門栅屏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來飘千,“玉大人,你說我怎么就攤上這事栈雳』つ危” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵哥纫,是天一觀的道長(zhǎng)霉旗。 經(jīng)常有香客問我,道長(zhǎng)蛀骇,這世上最難降的妖魔是什么厌秒? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮松靡,結(jié)果婚禮上简僧,老公的妹妹穿的比我還像新娘。我一直安慰自己雕欺,他們只是感情好岛马,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屠列,像睡著了一般啦逆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笛洛,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天夏志,我揣著相機(jī)與錄音,去河邊找鬼苛让。 笑死沟蔑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的狱杰。 我是一名探鬼主播瘦材,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼仿畸!你這毒婦竟也來了食棕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤错沽,失蹤者是張志新(化名)和其女友劉穎簿晓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體千埃,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡憔儿,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了放可。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片皿曲。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡唱逢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屋休,到底是詐尸還是另有隱情,我是刑警寧澤备韧,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布劫樟,位于F島的核電站,受9級(jí)特大地震影響织堂,放射性物質(zhì)發(fā)生泄漏叠艳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一易阳、第九天 我趴在偏房一處隱蔽的房頂上張望附较。 院中可真熱鬧,春花似錦潦俺、人聲如沸拒课。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽早像。三九已至,卻和暖如春肖爵,著一層夾襖步出監(jiān)牢的瞬間卢鹦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工劝堪, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留冀自,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓秒啦,卻偏偏與公主長(zhǎng)得像熬粗,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帝蒿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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