日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python类的特殊方法汇总_Python笔记001-类的特殊方法

發(fā)布時間:2024/8/23 python 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python类的特殊方法汇总_Python笔记001-类的特殊方法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python筆記001-類的特殊方法

以下是我學(xué)習(xí)《流暢的Python》后的個人筆記,現(xiàn)在拿出來和大家共享,希望能幫到各位Python學(xué)習(xí)者。

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關(guān)注。

本篇主要知識點:

類的特殊方法(一般都在前后帶有兩個下劃線,比如__len__和__getitem__),其存在的目的是被Python解釋器調(diào)用,而不是類的對象來調(diào)用。

對于自定義的類,一般無法體現(xiàn)出Python語言的核心特性,比如迭代和切片等,但是可以通過在自定義類中復(fù)寫__len__和__getitem__等特殊方法來實現(xiàn)這些核心功能。對象調(diào)用len()方法時實際上Python解釋器調(diào)用的是自定義類中的__len__,而對某個對象進行切片獲取元素,或者排序時,Python解釋器調(diào)用的是復(fù)寫的__getitem__。

在自定義類中復(fù)寫__getitem__至少可以獲得1.類對象的切片和獲取元素,2.對類對象進行迭代,可以是順序迭代也可以是逆序迭代,3.對類對象進行重新排序,4.對類對象進行隨機抽樣等多種功能。

類的特殊方法有多達(dá)100種,作為示例,此處僅僅總結(jié)了加減乘除等的復(fù)寫方法,并將所有特殊方法都整理成相關(guān)表格,便于后續(xù)復(fù)寫某些特殊方法時作為參考。

1. 特殊方法示例

這些特殊方法長得比較奇怪,那是因為它提醒用戶,不要輕易調(diào)用這些方法,因為它基本上是Python解釋器專用。

比如下面先建立一整副紙牌,它包含有一個屬性_cards,這個一個list,包含有52個Card對象。在復(fù)寫了__len__和__getitem__方法之后,就可以直接獲取到這個_cards屬性的總長度和對其進行排序,切片來獲取某幾張紙牌。

from collections import namedtuple

Card=namedtuple('Card', ['rank', 'suit']) # 單張紙牌類

class FrenchDeck: # 一副紙牌,包含4種花色,每種13種數(shù)字

ranks = [str(n) for n in range(2, 11)] + list('JQKA') # 13種數(shù)字

suits = 'spades diamonds clubs hearts'.split() # 四種不同花色:黑桃,方塊,梅花,紅桃

def __init__(self):

self._cards = [Card(rank, suit) for suit in self.suits

for rank in self.ranks]

# _cards屬性是所有紙牌的集合,一個list, 包含4種花色共52張牌

def __len__(self):

# 類FrechDeck的特殊方法:會計算所有紙牌的張數(shù),即52

return len(self._cards)

def __getitem__(self, position):

# 類FrechDeck的特殊方法:從52張牌獲取第position張牌

return self._cards[position]

構(gòu)建一副紙牌后,我們想知道里面有多少張牌,或者想知道第1張,第10張,最后一張紙牌分別是什么:

## 通過len()獲取deck中一共有多少張牌

deck=FrenchDeck()

print(len(deck)) # 52

## 通過切片方法獲取某個位置的牌

print(deck[0]) # Card(rank='2', suit='spades')

print(deck[10]) # Card(rank='Q', suit='spades')

print(deck[-1]) # Card(rank='A', suit='hearts')

如果沒有復(fù)寫__len__函數(shù),在len(deck)時會報錯:TypeError: object of type 'FrenchDeck' has no len().

同理,如果沒有復(fù)寫__getitem__方法,在deck[0]時報錯:TypeError: 'FrenchDeck' object does not support indexing

可以對deck進行索引來獲取某一個位置的紙牌,那么也就可以通過切片來獲取一個批次,符合一定條件的紙牌,比如下面獲取最后三張牌和牌面全是A的牌。

print(deck[-3:]) # 獲取最后三張牌

print(deck[12::13]) # 獲取全是A的牌,間隔型切片

同理,復(fù)寫了__getitem__方法后,就可以對deck對象進行迭代,不管是順序迭代還是逆序迭代都可以。

# 順序迭代

for card in deck[:10]: # 只打印最前面的10張牌

print(card)

# 逆序迭代

for card in reversed(deck[-10:]): # 只打印最后面的10張牌

print(card)

還可以判斷某張牌是否存在于該副牌內(nèi):

## 判斷某張牌是否存在于該副牌內(nèi):

print(Card('Q', 'hearts') in deck) # True

print(Card('Z', 'clubs') in deck) # False

有了__getitem__方法,就可以對所有紙牌進行排序操作,此處我們排序的規(guī)定是:梅花2最小,方塊2次之,紅桃2,黑桃2,梅花3.。。這種形式,所以要自定義一個排序方法,這個方法返回一個整數(shù),代表每張牌的大小,那么最小的梅花2就是0,最大的黑桃A就是51。

## 使用自定義方法對所有紙牌進行重新排序

suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0) # 將花色轉(zhuǎn)換為數(shù)值

def spades_high(card):

rank_value = FrenchDeck.ranks.index(card.rank) # 獲取某張牌的數(shù)字

return rank_value * len(suit_values) + suit_values[card.suit]

# 將某張牌的數(shù)字和花色換成整數(shù)返回

for card in sorted(deck, key=spades_high):

# 按照自定義方法spades_high得到的整數(shù)進行排序

print(card)

小結(jié)一下:自定義類通過復(fù)寫__getitem__方法,可以獲得多種原來不存在的功能:比如切片功能,索引功能,還可以判斷某個對象是否存在于類對象列表中,還可以對類對象進行迭代操作和排序操作。

2. 特殊方法的使用

對于自定義的類型,使用這些特殊方法可以使得他們的表現(xiàn)具有某些Python核心功能,在你對這些自定義類型進行操作時,比如len(deck)時,Python解釋器會去找deck類的__len__方法。

而Python內(nèi)置的類型,比如list, str, tuple等,Python解釋器則直接抄近路,會直接返回PyVarObject里的Ob_size屬性,這是一個長度可變的C語言結(jié)構(gòu)體,所以速度要比調(diào)用__len__方法快得多。

你自己對這些特殊方法的使用頻率會很低,因為都是Python解釋器自動調(diào)用,只有類定義時的__init__方法例外。

2.1 自定義加減乘除功能

class Person:

def __init__(self,name,age,score):

self.name=name

self.age=age

self.score=score

def __add__(self,other):

# 此處僅僅是將得分相加

return self.score+other.score

def __sub__(self,other):

# 此處將得分相減

return self.score-other.score

def __mul__(self,other):

# 此處將兩個的年齡相乘

return self.age*other.age

def __truediv__(self,other):

# 將兩個的得分相除

return self.score/other.score

這個自定義類Person復(fù)寫了加減乘除方法,根據(jù)需要對里面的屬性進行算術(shù)操作,那么就可以用符號+,-,*,/等進行操作,比如:

P1=Person('Jack',20,90)

P2=Person('Rose',18,60)

print(P1+P2) # 150

print(P1-P2) # 30

print(P1*P2) # 360

print(P1/P2) # 1.5

2.2 自定義print后的形式

還有一個非常常用的特殊函數(shù):__repr__,它決定了print被直接調(diào)用后結(jié)果表現(xiàn)形式。

class Person:

def __init__(self,name,age,score):

self.name=name

self.age=age

self.score=score

def __repr__(self):

return 'Person(name={},age={},score={})'.format(self.name,self.age,self.score)

P1=Person('Jack',20,90)

print(P1) # Person(name=Jack,age=20,score=90)

如果沒有復(fù)寫__repr__,在用print(P1)時,會得到內(nèi)存地址信息,人眼無法判斷出具體內(nèi)容,復(fù)寫之后,就可以按照我們想要的形式直接print。

3. 特殊方法匯總

Python內(nèi)置的特殊方法有將近一百種,其中有很多是實現(xiàn)算數(shù)運算,位運算和比較操作的,下面將這些方法的意義總結(jié)如下:

所以,如果自定義類想實現(xiàn)某方面的功能,可以參考上面的表格來逐一實現(xiàn)即可。

首次發(fā)表于: 微信公眾號:科技老丁哥,ID: TechDing,敬請關(guān)注。

本文所有代碼都已經(jīng)上傳到我的github,歡迎下載

參考資料:

《流暢的Python》,Luciano Ramalho (作者) 安道 , 吳珂 (譯者)。

總結(jié)

以上是生活随笔為你收集整理的python类的特殊方法汇总_Python笔记001-类的特殊方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。