Python中魔法方法的學(xué)習(xí)

概念解析

魔法方法是python的一種高級(jí)語(yǔ)法布持,他們是可以給你的類增加“magic”的特殊方法洗做,比如:增加一些額外的功能驯嘱。函數(shù)格式為_(kāi) xx _(被雙下劃線包圍的函數(shù))灶壶。

魔法方法

  • 基本定制
object.__init__(self, *args, **kwargs)  # 構(gòu)造器义郑,創(chuàng)建完對(duì)象后調(diào)用蝶柿,進(jìn)行當(dāng)前實(shí)例的初始化
object.__new__(cls, *args, **kwargs)    # 構(gòu)造器,創(chuàng)建對(duì)象時(shí)調(diào)用非驮,返回值是一個(gè)對(duì)象
object.__del__(self)                    # 解構(gòu)器交汤,刪除對(duì)象時(shí)調(diào)用
object.__str__(self)                    # 若類C中實(shí)現(xiàn)此方法,當(dāng)str(C())時(shí)此方法被調(diào)用
object.__len__(self)                    # 若類C中實(shí)現(xiàn)此方法劫笙,當(dāng)len(C())時(shí)此方法被調(diào)用

測(cè)試代碼如下:

# coding=utf-8
class MagicDemo(object):
    def __init__(self):
        """對(duì)當(dāng)前對(duì)象的實(shí)例的一些初始化"""
        print "call me second"
        self.value = [1, 2, 3]

    def __new__(cls, *args, **kwargs):
        """
        真正的構(gòu)造函數(shù)芙扎,先于__init__調(diào)用,
        返回創(chuàng)建的對(duì)象
        """
        print "call me first"
        return super(MagicDemo, cls).__new__(cls, *args, **kwargs)

    def __del__(self):
        print "call __del__"
        del self

    def __len__(self):
        print "call __len__"
        return len(self.value)

    def __str__(self):
        return "call __str__"
if __name__ == '__main__':
    mag = MagicDemo()
    print mag.value
    print len(mag)
    print str(mag)
    del mag

運(yùn)行結(jié)果如下:

call me first
call me second
[1, 2, 3]
call __len__
3
call __str__
call __del__
  • 比較函數(shù)
object.__lt__(self, obj)                # 小于比較 <
object.__le__(self, obj)                # 小于或等于 <=
object.__gt__(self, obj)                # 大于 >
object.__ge__(self, obj)                # 大于多等于 >=
object.__eq__(self, obj)                # 等于 ==
object.__ne__(self, obj)                # 不等于 !=

測(cè)試代碼如下:

# coding=utf-8
class MagicDemo(object):
    def __init__(self, value):
        self.value = value

    def __lt__(self, obj):
        print "call the __lt__"
        return self.value < obj.value

    def __le__(self, obj):
        print "call the __le__"
        return self.value <= obj.value

    def __gt__(self, obj):
        print "call the __gt__"
        return self.value > obj.value

    def __ge__(self, obj):
        print "call the __ge__"
        return self.value >= obj.value

    def __eq__(self, obj):
        print "call the __eq__"
        return self.value == obj.value

    def __ne__(self, obj):
        print "call the __ne__"
        return self.value != obj.value
if __name__ == '__main__':
    mag1 = MagicDemo(5)
    mag2 = MagicDemo(6)
    print mag1 < mag2
    print mag1 <= mag2
    print mag1 > mag2
    print mag1 >= mag2
    print mag1 == mag2
    print mag1 != mag2

運(yùn)行結(jié)果如下:

call the __lt__
True
call the __le__
True
call the __gt__
False
call the __ge__
False
call the __eq__
False
call the __ne__
True
  • 屬性操作
object.__getattr__(self, attr)                   # 獲取屬性填大,僅當(dāng)屬性找不到時(shí)被調(diào)用
object.__setattr__(self, attr, val)              # 設(shè)置屬性戒洼,當(dāng)設(shè)置屬性的值時(shí)被調(diào)用
object.__delattr__(self, attr)                   # 刪除屬性時(shí)被調(diào)用
object.__getattribute__(self, attr)              # 獲取屬性,總是被調(diào)用允华,發(fā)生異常時(shí)調(diào)用__getattr__
object.__get__(self, attr)                       #(描述符)獲取屬性
object.__set__(self, attr, val)                  #(描述符)設(shè)置屬性
object.__delete__(self, attr)                    #(描述符)刪除屬性

測(cè)試代碼(描述符的三個(gè)屬性暫不說(shuō)明)

# coding=utf-8
class MagicDemo(object):
    def __init__(self, value):
        self.value = value

    def __getattr__(self, attr):
        """找不到屬性時(shí)被調(diào)用"""
        print "call __getattr__"
        return "%s no found" % attr

    def __setattr__(self, attr, value):
        print "call __setattr__"
        self.__dict__[attr] = value

    def __delattr__(self, attr):
        print "call __delattr__"
        del self.__dict__[attr]

    def __getattribute__(self, attr):
        """此方法只適用于新式類"""
        print "call __getattribute__"
        # return self.__dict__[name]
        # 為了避免陷入死循環(huán)
        return object.__getattribute__(self, attr)
if __name__ == '__main__':
    mag = MagicDemo(5)
    print "_______________"
    mag.value = 6
    print "_______________"
    print mag.value
    print "_______________"
    print mag.xxx

測(cè)試結(jié)果如下:

call __setattr__
call __getattribute__
_______________
call __setattr__
call __getattribute__
_______________
call __getattribute__
6
_______________
call __getattribute__
call __getattr__
xxx no found

可以看出施逾,當(dāng)訪問(wèn)對(duì)象的屬性時(shí)敷矫,__getattribute__總是被調(diào)用(新式類中有效),當(dāng)找不到屬性時(shí)汉额,將調(diào)用__getattr__曹仗。其中__getattribute__調(diào)用基類的方法是為了陷入死循環(huán),因?yàn)?code>__getattribute__總是無(wú)條件的被調(diào)用蠕搜。

  • 自定義序列
object.__getitem__(self, key)                    # 得到單個(gè)序列元素
object.__setitem__(self, key, val)               # 設(shè)置單個(gè)序列元素
object.__delitem__(self, key)                    # 刪除單個(gè)序列元素
object.__contains__(self, key)                   # 測(cè)試序列元素怎茫,使用in時(shí)調(diào)用
object.__iter__(self)                            # 返回一個(gè)迭代器

測(cè)試代碼:

# coding=utf-8
class MagicDemo(object):
    def __init__(self):
        self.value = dict()

    def __getitem__(self, key):
        print "call the __getitem__"
        return self.value[key]

    def __setitem__(self, key, val):
        print "call the __setitem__"
        self.value[key] = val

    def __delitem__(self, key):
        print "call the __delitem__"
        del self.value[key]

    def __contains__(self, key):
        print "call the __contains__"
        return key in self.value

if __name__ == '__main__':
    mag = MagicDemo()
    mag["name"] = "hello"
    print "_______________"
    print mag["name"]
    print "_______________"
    print "xxx" in mag

測(cè)試結(jié)果如下:

call the __setitem__
_______________
call the __getitem__
hello
_______________
call the __contains__
False

需要注意的是當(dāng)屬性為dict時(shí)通過(guò)鍵值對(duì)進(jìn)行賦值,當(dāng)為list時(shí)妓灌,通過(guò)下標(biāo)進(jìn)行賦值轨蛤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市虫埂,隨后出現(xiàn)的幾起案子祥山,更是在濱河造成了極大的恐慌,老刑警劉巖掉伏,帶你破解...
    沈念sama閱讀 212,884評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缝呕,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡斧散,警方通過(guò)查閱死者的電腦和手機(jī)供常,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)鸡捐,“玉大人栈暇,你說(shuō)我怎么就攤上這事」烤担” “怎么了源祈?”我有些...
    開(kāi)封第一講書人閱讀 158,369評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)色迂。 經(jīng)常有香客問(wèn)我香缺,道長(zhǎng),這世上最難降的妖魔是什么脚草? 我笑而不...
    開(kāi)封第一講書人閱讀 56,799評(píng)論 1 285
  • 正文 為了忘掉前任赫悄,我火速辦了婚禮原献,結(jié)果婚禮上馏慨,老公的妹妹穿的比我還像新娘。我一直安慰自己姑隅,他們只是感情好写隶,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著讲仰,像睡著了一般慕趴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 50,096評(píng)論 1 291
  • 那天冕房,我揣著相機(jī)與錄音躏啰,去河邊找鬼。 笑死耙册,一個(gè)胖子當(dāng)著我的面吹牛给僵,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播详拙,決...
    沈念sama閱讀 39,159評(píng)論 3 411
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼帝际,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了饶辙?” 一聲冷哼從身側(cè)響起蹲诀,我...
    開(kāi)封第一講書人閱讀 37,917評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弃揽,沒(méi)想到半個(gè)月后脯爪,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蹋宦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評(píng)論 2 327
  • 正文 我和宋清朗相戀三年披粟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冷冗。...
    茶點(diǎn)故事閱讀 38,814評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡守屉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蒿辙,到底是詐尸還是另有隱情拇泛,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評(píng)論 4 334
  • 正文 年R本政府宣布思灌,位于F島的核電站俺叭,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏泰偿。R本人自食惡果不足惜熄守,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耗跛。 院中可真熱鬧裕照,春花似錦、人聲如沸调塌。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)羔砾。三九已至负间,卻和暖如春偶妖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背政溃。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,123評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工趾访, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人董虱。 一個(gè)月前我還...
    沈念sama閱讀 46,641評(píng)論 2 362
  • 正文 我出身青樓腹缩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親空扎。 傳聞我的和親對(duì)象是個(gè)殘疾皇子藏鹊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評(píng)論 2 351

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

  • 南高原的天空 四季都產(chǎn)春 只要你爬上山峰 選一片開(kāi)闊地躺下 太陽(yáng)正好照在你身上 不管睜眼還是閉眼 你都會(huì)感覺(jué)到清新...
    王子的夜宴閱讀 362評(píng)論 1 3
  • 還是先上作品圖 首先,先畫底稿 后面顏色可自行搭配我圖涂完顏色是這樣的 怎么樣,是不是挺好看的,我期待你的創(chuàng)作!
    愷歌閱讀 520評(píng)論 1 4
  • 今天晚上,我寫完了作業(yè)我和媽媽開(kāi)始種吊蘭转锈。我們先把土裝進(jìn)花盆里盘寡,然后我們?cè)購(gòu)拇蟮跆m上摘下一些小的吊蘭,種到花盆兒里...
    靜如思閱讀 182評(píng)論 0 1
  • 我所有的情感 都像被月光浸透過(guò) 所有的夏天 都被雨水浸透過(guò) 城市多變燈光的情義 沉默的石頭擊碎了噩夢(mèng) 八月的月撮慨,八...
    臨晚閱讀 495評(píng)論 4 15