成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Python進(jìn)階:自定義對(duì)象實(shí)現(xiàn)切片功能

yangrd / 3515人閱讀

摘要:以自定義字典為例僅作演示,不保證其它功能的完備性貓輸出結(jié)果上例的關(guān)鍵點(diǎn)在于將字典的鍵值取出,并對(duì)鍵值的列表做切片處理,其妙處在于,不用擔(dān)心索引越界和負(fù)數(shù)索引,將字典切片轉(zhuǎn)換成了字典鍵值的切片,最終實(shí)現(xiàn)目的。

2018-12-31 更新聲明:切片系列文章本是分三篇寫成,現(xiàn)已合并成一篇。合并后,修正了一些嚴(yán)重的錯(cuò)誤(如自定義序列切片的部分),還對(duì)行文結(jié)構(gòu)與章節(jié)銜接做了大量改動(dòng)。原系列的單篇就不刪除了,畢竟也是有多帶帶成篇的作用。特此聲明,請閱讀改進(jìn)版—— Python進(jìn)階:全面解讀高級(jí)特性之切片!https://mp.weixin.qq.com/s/IR...

切片是 Python 中最迷人最強(qiáng)大最 Amazing 的語言特性(幾乎沒有之一),在《Python進(jìn)階:切片的誤區(qū)與高級(jí)用法》中,我介紹了切片的基礎(chǔ)用法、高級(jí)用法以及一些使用誤區(qū)。這些內(nèi)容都是基于原生的序列類型(如字符串、列表、元組......),那么,我們是否可以定義自己的序列類型并讓它支持切片語法呢?更進(jìn)一步,我們是否可以自定義其它對(duì)象(如字典)并讓它支持切片呢?

1、魔術(shù)方法:__getitem__()

想要使自定義對(duì)象支持切片語法并不難,只需要在定義類的時(shí)候給它實(shí)現(xiàn)魔術(shù)方法 __getitem__() 即可。所以,這里就先介紹一下這個(gè)方法。

語法: object.__getitem__(self, key)

官方文檔釋義:Called to implement evaluation of self[key]. For sequence types, the accepted keys should be integers and slice objects. Note that the special interpretation of negative indexes (if the class wishes to emulate a sequence type) is up to the __getitem__() method. If key is of an inappropriate type, TypeError may be raised; if of a value outside the set of indexes for the sequence (after any special interpretation of negative values), IndexError should be raised. For mapping types, if key is missing (not in the container), KeyError should be raised.

概括翻譯一下:__getitem__() 方法用于返回參數(shù) key 所對(duì)應(yīng)的值,這個(gè) key 可以是整型數(shù)值和切片對(duì)象,并且支持負(fù)數(shù)索引;如果 key 不是以上兩種類型,就會(huì)拋 TypeError;如果索引越界,會(huì)拋 IndexError ;如果定義的是映射類型,當(dāng) key 參數(shù)不是其對(duì)象的鍵值時(shí),則會(huì)拋 KeyError 。

2、自定義序列實(shí)現(xiàn)切片功能

接下來,我們定義一個(gè)簡單的 MyList ,并給它加上切片功能。(PS:僅作演示,不保證其它功能的完備性)。

class MyList():
    def __init__(self):
        self.data = []
    def append(self, item):
        self.data.append(item)
    def __getitem__(self, key):
        print("key is : " + str(key))
        return self.data[key]

l = MyList()
l.append("My")
l.append("name")
l.append("is")
l.append("Python貓")

print(l[3])
print(l[:2])
print(l["hi"])

### 輸出結(jié)果:
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

從輸出結(jié)果來看,自定義的 MyList 既支持按索引查找,也支持切片操作,這正是我們的目的。

特別需要說明的是,此例中的 __getitem__() 方法會(huì)根據(jù)不同的參數(shù)類型而實(shí)現(xiàn)不同的功能(取索引位值或切片值),也會(huì)妥當(dāng)?shù)靥幚懋惓#圆⒉恍枰覀冊偃懛爆嵉奶幚磉壿?。網(wǎng)上有不少學(xué)習(xí)資料完全是在誤人子弟,它們會(huì)教你區(qū)分參數(shù)的不同類型,然后寫一大段代碼來實(shí)現(xiàn)索引查找和切片語法,簡直是畫蛇添足。下面的就是一個(gè)代表性的錯(cuò)誤示例:

###略去其它代碼####
def __getitem__(self, index):
    cls = type(self)
    if isinstance(index, slice):  # 如果index是個(gè)切片類型,則構(gòu)造新實(shí)例
       return cls(self._components[index])
    elif isinstance(index, numbers.Integral):  # 如果index是個(gè)數(shù),則直接返回
        return self._components[index]
    else:
        msg = "{cls.__name__} indices must be integers"
        raise TypeError(msg.format(cls=cls))
3、自定義字典實(shí)現(xiàn)切片功能

切片是序列類型的特性,所以在上例中,我們不需要寫切片的具體實(shí)現(xiàn)邏輯。但是,對(duì)于其它非序列類型的自定義對(duì)象,就得自己實(shí)現(xiàn)切片邏輯。以自定義字典為例(PS:僅作演示,不保證其它功能的完備性):

class MyDict():
    def __init__(self):
        self.data = {}
    def __len__(self):
        return len(self.data)
    def append(self, item):
        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 {k: self.data[k] for k in slicedkeys}
        else:
            raise TypeError

d = MyDict()
d.append("My")
d.append("name")
d.append("is")
d.append("Python貓")
print(d[2])
print(d[:2])
print(d[-4:-2])
print(d["hi"])

### 輸出結(jié)果:
is
{0: "My", 1: "name"}
{0: "My", 1: "name"}
Traceback (most recent call last):
...
TypeError

上例的關(guān)鍵點(diǎn)在于將字典的鍵值取出,并對(duì)鍵值的列表做切片處理,其妙處在于,不用擔(dān)心索引越界和負(fù)數(shù)索引,將字典切片轉(zhuǎn)換成了字典鍵值的切片,最終實(shí)現(xiàn)目的。

4、小結(jié)

最后小結(jié)一下:本文介紹了__getitem__() 魔術(shù)方法,并用于實(shí)現(xiàn)自定義對(duì)象(以列表類型和字典類型為例)的切片功能,希望對(duì)你有所幫助。

參考閱讀:

Python進(jìn)階:切片的誤區(qū)與高級(jí)用法

官方文檔getitem用法:http://t.cn/EbzoZyp

Python切片賦值源碼分析:http://t.cn/EbzSaoZ

PS:本公眾號(hào)(Python貓)已開通讀者交流群,詳情請通過菜單欄中的“交流群”來了解。

-----------------

本文原創(chuàng)并首發(fā)于微信公眾號(hào)【Python貓】,后臺(tái)回復(fù)“愛學(xué)習(xí)”,免費(fèi)獲得20+本精選電子書。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/42887.html

相關(guān)文章

  • Python進(jìn)階:迭代器與迭代器切片

    摘要:本文是切片系列的第三篇,主要內(nèi)容是迭代器切片。實(shí)際上,迭代器必然是可迭代對(duì)象,但可迭代對(duì)象不一定是迭代器。這是迭代器切片最具想象力的用途場景??紤]到文件對(duì)象天然就是迭代器,我們可以使用迭代器切片先行截取,然后再處理,如此效率將大大地提升。 2018-12-31 更新聲明:切片系列文章本是分三篇寫成,現(xiàn)已合并成一篇。合并后,修正了一些嚴(yán)重的錯(cuò)誤(如自定義序列切片的部分),還對(duì)行文結(jié)構(gòu)與章...

    hedge_hog 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<