python 魔法函數(shù)實(shí)例及解析
python的幾個(gè)魔法函數(shù)
__repr__
Python中這個(gè)__repr__函數(shù),對應(yīng)repr(object)這個(gè)函數(shù),返回一個(gè)可以用來表示對象的可打印字符串.如果我們直接打印一個(gè)類,向下面這樣
class A(): def __init__(self,name=None,id=1): self.id=id self.name=name if __name__ == '__main__': a=A() print(a)
輸出結(jié)果
<__main__.A object at 0x0000018DF8E7EAC8>
不是很友好,返回了一個(gè)對象的內(nèi)存地址。我們改成下面再次輸出
class A(): def __init__(self,name=None,id=1): self.id=id self.name=name def __repr__(self): return "進(jìn)入函數(shù)" if __name__ == '__main__': print(A())
輸出結(jié)果
進(jìn)入函數(shù)
__str__
class A(): def __init__(self,name=None,id=1): self.id=id self.name=name def __str__(self): return "進(jìn)入函數(shù)" if __name__ == '__main__': print(A())
輸出結(jié)果
進(jìn)入函數(shù)
比較repr和str
上面我們發(fā)現(xiàn)在print的時(shí)候,兩個(gè)魔法函數(shù)顯示的效果是一樣的,那這兩個(gè)魔法函數(shù)區(qū)別在哪呢,__repr__和__str__這兩個(gè)方法都是用于顯示的,__str__是面向用戶的,而__repr__面向程序員。在print的時(shí)候兩者項(xiàng)目一樣,但是在交互命令下__repr__同樣有著print的效果,但是__str__還是輸出對象內(nèi)存地址。也就說在交互式命令下我們可以看到其效果,另外__str__ 方法其實(shí)調(diào)用了 __repr__ 方法。
__getitem__
如果在類中定義了getitem__()方法,那么他的實(shí)例對象(假設(shè)為A)就可以這樣A[key]取值。當(dāng)實(shí)例對象做A[key]運(yùn)算時(shí),就會(huì)調(diào)用類中的__getitem()方法。
class A(): def __init__(self,name=None,id=1): self.id=id self.name=name def __repr__(self): return "進(jìn)入函數(shù)" def __getitem__(self, item): return item if __name__ == '__main__': a=A('lisa','123') print(a['name']) print(a[124])
輸出
name 124
實(shí)例對象的key不管是否存在都會(huì)調(diào)用類中的__getitem__()方法。而且返回值就是__getitem__()方法中規(guī)定的return值。也就是說如果getitem里的方法寫的不好就沒有了意義了。我們修改下代碼,改變getitem的return的值
class A(): def __init__(self,name=None,id=1): self.id=id self.name=name def __repr__(self): return "進(jìn)入函數(shù)" def __getitem__(self, item): return self.__dict__[item] if __name__ == '__main__': a=A('lisa','123') print(a['name']) print(a[123])
輸出
lisa keyerror:123
輸出了lisa和一個(gè)異常,改后的getitem做了什么事呢,self.__dict__,是獲取當(dāng)前實(shí)例的所有屬性的字典格式,后面的[item]就是取其對于的鍵值,這里我傳了個(gè)name,實(shí)際就是取name屬性的值也就是lisa。對于123因?yàn)椴淮嬖谶@個(gè)屬性所有報(bào)錯(cuò)了。這也是字典內(nèi)部實(shí)現(xiàn)的一部分。
再來看一個(gè)例子,代碼里已經(jīng)加入了注釋:
import collections Card = collections.namedtuple('Card', ['rank', 'suit']) # 具名元組動(dòng)態(tài)創(chuàng)建一個(gè)類Card,并含有兩個(gè)屬性rank和suit # 用以構(gòu)建只有少數(shù)屬性但是沒有方法的對象 class FrenchDeck: ranks = [str(n) for n in range(2, 11)] + list('JQKA') # 撲克牌2到A組成的列表 suits = 'spades diamonds clubs hearts'.split() # 四種花色 def __init__(self): self._cards = [Card(rank, suit) for suit in self.suits for rank in self.ranks] # 笛卡爾積,13*4=52(除去兩個(gè)王) def __len__(self): return len(self._cards) def __getitem__(self, position): # 調(diào)用f[0]時(shí)會(huì)進(jìn)入 return self._cards[position] if __name__ == '__main__': f = FrenchDeck() print(f[0]) # 在這里f[0]實(shí)際是f.__getitem__(0)
輸出
Card(rank='2', suit='spades')
我們發(fā)現(xiàn)這個(gè)例子中還有一個(gè)__len__,那這個(gè)方法是干嘛的呢,我們繼續(xù)往下看
__len__
在上面的例子中我們使用該方法,這個(gè)方法會(huì)在什么情況下發(fā)生呢,一個(gè)小例子來說明。
class B():
class B(): def __init__(self): self.a_list = range(10) def __len__(self): return len(self.a_list) if __name__ == '__main__': b = B() print(len(b)) #在這里等價(jià)于 #print(b.__len__())
輸出
10
我們在調(diào)用len方法的時(shí)候會(huì)調(diào)用__len__。
__setitem__
__setitem__(self,key,value):該方法應(yīng)該按一定的方式存儲(chǔ)和key相關(guān)的value。在設(shè)置類實(shí)例屬性時(shí)自動(dòng)調(diào)用的。
class B():
class B(): def __init__(self): self.a_list = range(10) def __setitem__(self, key, value): self.__dict__[key] = value def cfun(a, b, c): print("新加入函數(shù)c") if __name__ == '__main__': b = B() b['a_list'] = "123" # 這個(gè)會(huì)調(diào)用B類的\__setitem_方法_ B.__setitem__ = cfun # 改變settime方式變?yōu)閏fun這個(gè)函數(shù) b['a_list'] = "123" # 這次實(shí)際會(huì)調(diào)用cfun函數(shù) print(b.a_list)
輸出
新加入函數(shù)c 123
__delitem__
執(zhí)行del函數(shù)的時(shí)候會(huì)調(diào)用,如果繼承了 繼承abc.MutableSequence的類就必須實(shí)現(xiàn) __delitem__ 方法,這是 MutableSequence 類的一個(gè)抽象方法。
__eq__
a == b等同于a.__eq__(b)。你可以在自己的類中定義 __eq__ 方法,決定 == 如何比較實(shí)例。如果不覆蓋 __eq__ 方法,那么從 object 繼承的方法比較
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python 監(jiān)聽salt job狀態(tài),并任務(wù)數(shù)據(jù)推送到redis中的方法
今天小編就為大家分享一篇python 監(jiān)聽salt job狀態(tài),并任務(wù)數(shù)據(jù)推送到redis中的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01ubuntu環(huán)境下python虛擬環(huán)境的安裝過程
這篇文章主要介紹了ubuntu環(huán)境下python虛擬環(huán)境的安裝搭建過程 ,需要的朋友可以參考下2018-01-01python 禁止函數(shù)修改列表的實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猵ython 禁止函數(shù)修改列表的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08通過shell+python實(shí)現(xiàn)企業(yè)微信預(yù)警
這篇文章主要介紹了通過shell+python實(shí)現(xiàn)企業(yè)微信預(yù)警,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-03-03python thrift 實(shí)現(xiàn) 單端口多服務(wù)的過程
這篇文章主要介紹了python thrift 實(shí)現(xiàn) 單端口多服務(wù)的過程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Python 整行讀取文本方法并去掉readlines換行\(zhòng)n操作
這篇文章主要介紹了Python 整行讀取文本方法并去掉readlines換行\(zhòng)n操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09Python進(jìn)程,多進(jìn)程,獲取進(jìn)程id,給子進(jìn)程傳遞參數(shù)操作示例
這篇文章主要介紹了Python進(jìn)程,多進(jìn)程,獲取進(jìn)程id,給子進(jìn)程傳遞參數(shù)操作,結(jié)合實(shí)例形式分析了Python多進(jìn)程、父子進(jìn)程以及進(jìn)程參數(shù)傳遞相關(guān)操作技巧,需要的朋友可以參考下2019-10-10