python 魔法函數(shù)實例及解析
python的幾個魔法函數(shù)
__repr__
Python中這個__repr__函數(shù),對應(yīng)repr(object)這個函數(shù),返回一個可以用來表示對象的可打印字符串.如果我們直接打印一個類,向下面這樣
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>
不是很友好,返回了一個對象的內(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ù)顯示的效果是一樣的,那這兩個魔法函數(shù)區(qū)別在哪呢,__repr__和__str__這兩個方法都是用于顯示的,__str__是面向用戶的,而__repr__面向程序員。在print的時候兩者項目一樣,但是在交互命令下__repr__同樣有著print的效果,但是__str__還是輸出對象內(nèi)存地址。也就說在交互式命令下我們可以看到其效果,另外__str__ 方法其實調(diào)用了 __repr__ 方法。
__getitem__
如果在類中定義了getitem__()方法,那么他的實例對象(假設(shè)為A)就可以這樣A[key]取值。當(dāng)實例對象做A[key]運(yùn)算時,就會調(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
實例對象的key不管是否存在都會調(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和一個異常,改后的getitem做了什么事呢,self.__dict__,是獲取當(dāng)前實例的所有屬性的字典格式,后面的[item]就是取其對于的鍵值,這里我傳了個name,實際就是取name屬性的值也就是lisa。對于123因為不存在這個屬性所有報錯了。這也是字典內(nèi)部實現(xiàn)的一部分。
再來看一個例子,代碼里已經(jīng)加入了注釋:
import collections
Card = collections.namedtuple('Card', ['rank', 'suit'])
# 具名元組動態(tài)創(chuàng)建一個類Card,并含有兩個屬性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(除去兩個王)
def __len__(self):
return len(self._cards)
def __getitem__(self, position):
# 調(diào)用f[0]時會進(jìn)入
return self._cards[position]
if __name__ == '__main__':
f = FrenchDeck()
print(f[0])
# 在這里f[0]實際是f.__getitem__(0)
輸出
Card(rank='2', suit='spades')
我們發(fā)現(xiàn)這個例子中還有一個__len__,那這個方法是干嘛的呢,我們繼續(xù)往下看
__len__
在上面的例子中我們使用該方法,這個方法會在什么情況下發(fā)生呢,一個小例子來說明。
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))
#在這里等價于
#print(b.__len__())
輸出
10
我們在調(diào)用len方法的時候會調(diào)用__len__。
__setitem__
__setitem__(self,key,value):該方法應(yīng)該按一定的方式存儲和key相關(guān)的value。在設(shè)置類實例屬性時自動調(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" # 這個會調(diào)用B類的\__setitem_方法_
B.__setitem__ = cfun # 改變settime方式變?yōu)閏fun這個函數(shù)
b['a_list'] = "123" # 這次實際會調(diào)用cfun函數(shù)
print(b.a_list)
輸出
新加入函數(shù)c 123
__delitem__
執(zhí)行del函數(shù)的時候會調(diào)用,如果繼承了 繼承abc.MutableSequence的類就必須實現(xiàn) __delitem__ 方法,這是 MutableSequence 類的一個抽象方法。
__eq__
a == b等同于a.__eq__(b)。你可以在自己的類中定義 __eq__ 方法,決定 == 如何比較實例。如果不覆蓋 __eq__ 方法,那么從 object 繼承的方法比較
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python登錄WeChat 實現(xiàn)自動回復(fù)實例詳解
在本篇內(nèi)容里小編給大家整理的是關(guān)于python登錄WeChat 實現(xiàn)自動回復(fù)的相關(guān)實例內(nèi)容以及知識點總結(jié),有興趣的朋友們參考下。2019-05-05
Python實現(xiàn)網(wǎng)站注冊驗證碼生成類
這篇文章主要為大家詳細(xì)介紹了Python實現(xiàn)網(wǎng)站注冊驗證碼生成類,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-06-06
Python深度學(xué)習(xí)之使用Albumentations對圖像做增強(qiáng)
諸如RandomCrop和CenterCrop之類的某些增強(qiáng)功能可能會變換圖像,使其不包含所有原始邊界框. 本示例說明如何使用名為RandomSizedBBoxSafeCrop的變換來裁剪圖像的一部分,但保留原始圖像的所有邊界框,需要的朋友可以參考下2021-05-05
Python機(jī)器學(xué)習(xí)應(yīng)用之基于線性判別模型的分類篇詳解
線性判別分析(Linear?Discriminant?Analysis,?LDA)是一種監(jiān)督學(xué)習(xí)的降維方法,也就是說數(shù)據(jù)集的每個樣本是有類別輸出。和之前介紹的機(jī)器學(xué)習(xí)降維之主成分分析(PCA)方法不同,PCA是不考慮樣本類別輸出的無監(jiān)督學(xué)習(xí)方法2022-01-01
解決mnist數(shù)據(jù)集下載的相關(guān)問題
這篇文章主要介紹了解決mnist數(shù)據(jù)集下載的相關(guān)問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
Python使用Tkinter實現(xiàn)機(jī)器人走迷宮
這篇文章主要為大家詳細(xì)介紹了Python使用Tkinter實現(xiàn)機(jī)器人走迷宮,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

