Python高階 自定義物件實現切片功能

2021-09-19 17:54:38 字數 2697 閱讀 8477

切片是 python 中最迷人最強大最 amazing 的語言特性(幾乎沒有之一),在《python高階:切片的誤區與高階用法》中,我介紹了切片的基礎用法、高階用法以及一些使用誤區。這些內容都是基於原生的序列型別(如字串、列表、元組......),那麼,我們是否可以定義自己的序列型別並讓它支援切片語法呢?更進一步,我們是否可以自定義其它物件(如字典)並讓它支援切片呢?

想要使自定義物件支援切片語法並不難,只需要在定義類的時候給它實現魔術方法__getitem__()即可。所以,這裡就先介紹一下這個方法。

語法:object.__getitem__(self, key)

概括翻譯一下:__getitem__()方法用於返回引數 key 所對應的值,這個 key 可以是整型數值和切片物件,並且支援負數索引;如果 key 不是以上兩種型別,就會拋 typeerror;如果索引越界,會拋 indexerror ;如果定義的是對映型別,當 key 引數不是其物件的鍵值時,則會拋 keyerror 。

接下來,我們定義乙個簡單的 mylist ,並給它加上切片功能。(ps:僅作演示,不保證其它功能的完備性)。

class mylist():

def __init__(self):

self.data =

def __getitem__(self, key):

print("key is : " + str(key))

return self.data[key]

l = mylist()

print(l[3])

print(l[:2])

print(l['hi'])

### 輸出結果:

key is : 3

python貓

key is : slice(none, 2, none)

['my', 'name']

key is : hi

traceback (most recent call last):

...typeerror: list indices must be integers or slices, not str

從輸出結果來看,自定義的 mylist 既支援按索引查詢,也支援切片操作,這正是我們的目的。

特別需要說明的是,此例中的__getitem__()方法會根據不同的引數型別而實現不同的功能(取索引位值或切片值),也會妥當地處理異常,所以並不需要我們再去寫繁瑣的處理邏輯。網上有不少學習資料完全是在誤人子弟,它們會教你區分引數的不同型別,然後寫一大段**來實現索引查詢和切片語法,簡直是畫蛇添足。下面的就是乙個代表性的錯誤示例:

###略去其它**####

def __getitem__(self, index):

cls = type(self)

if isinstance(index, slice): # 如果index是個切片型別,則構造新例項

return cls(self._components[index])

elif isinstance(index, numbers.integral): # 如果index是個數,則直接返回

return self._components[index]

else:

msg = " indices must be integers"

raise typeerror(msg.format(cls=cls))

切片是序列型別的特性,所以在上例中,我們不需要寫切片的具體實現邏輯。但是,對於其它非序列型別的自定義物件,就得自己實現切片邏輯。以自定義字典為例(ps:僅作演示,不保證其它功能的完備性):

class mydict():

def __init__(self):

self.data = {}

def __len__(self):

return len(self.data)

self.data[len(self)] = item

def __getitem__(self, key):

if isinstance(key, int):

return self.data[key]

if isinstance(key, slice):

slicedkeys = list(self.data.keys())[key]

return

else:

raise typeerror

d = mydict()

print(d[2])

print(d[:2])

print(d[-4:-2])

print(d['hi'])

### 輸出結果:

istraceback (most recent call last):

...typeerror

上例的關鍵點在於將字典的鍵值取出,並對鍵值的列表做切片處理,其妙處在於,不用擔心索引越界和負數索引,將字典切片轉換成了字典鍵值的切片,最終實現目的。

最後小結一下:本文介紹了__getitem__()魔術方法,並用於實現自定義物件(以列表型別和字典型別為例)的切片功能,希望對你有所幫助。

Python高階 自定義物件實現切片功能

切片是 python 中最迷人最強大最 amazing 的語言特性 幾乎沒有之一 在 python高階 切片的誤區與高階用法 中,我介紹了切片的基礎用法 高階用法以及一些使用誤區。這些內容都是基於原生的序列型別 如字串 列表 元組.那麼,我們是否可以定義自己的序列型別並讓它支援切片語法呢?更進一步,...

python高階 自定義庫函式

在python使用過程中,在不同的專案裡,常常會出現頻繁地自定義同乙個函式的情況。為了解決這個問題,我們可以選擇建立乙個自定義的庫,並將其新增到系統路徑中 具體操作如下 在任意位置新建乙個專案my libs,並在其中新建python檔案my lib1和my lib2,將需要自定義的函式在my lib...

物件陣列。自定義物件

定義學生類屬性 自定義方法 顯示學生資訊方法年齡增加方法測試類 建立用於儲存學生的陣列,長度為5,建立5個學生物件,將物件儲存到陣列中遍歷陣列中的學生物件,分別呼叫年齡增加方法,將學生年齡增加2遍歷陣列中的學生物件,分別呼叫顯示資訊的方法,檢視所有學生資訊查詢年齡大於20的學生資訊 針對這個作業。寫...