1、背景
在工作中,我們往往需要定義自己的資料結構,能夠使資料進行有效的讀取、序列結構就是重要的資料結構之一,利用python中的list、tuple、str、dict等都是一些内置的序列結構,我們可以用len()函數傳回序列長度或者for循環進行周遊元素,但實際上python的解釋器會在實作這些功能自動調用資料類中的特殊方法,例如len()調用的就是__len__(),for循環調用的是__iter__(),實際上python中的特殊方法是非常強大,能夠幫助我們有效的利用資料。
2、iterable、iterator、sequence
這裡來說一說iterable和iterator、以及sequence的差別。
iterable實際上是一個類對象,任何包含__iter__()或者__getitem__()的方法的對象,都可以被認為是一個iterable。
sequence首先iterable的一種,顧名思義,sequence就是有有序的iterable,可以通過整數索引來通路其中的元素。是以在sequence中需要定義__len__()和__getitem__()方法。
iterator對象的實作必須滿足疊代協定,python中這種疊代協定通過__next__()和__iter__()來實作。
(在hash類型資料中,__iter__()不能被__getitem__()代替。)
iterator用next()函數或者__next__()來通路元素,且每次通路iterator都會更新,能夠更有效率的利用記憶體(通路完iterator就被清空了)。
這裡放一個前面深度學習定義的資料序列:
import os
from torch import nn
from PIL import Image
import numpy as np
class Mydataset(nn.module):
def __init__(self, images_dir:str,masks_dir:str, class_num:int, transform):
super(Mydataset,self).__init__():
self.class_num=class_num
self.names=os.listdir(images_dir)
self.images_fps=[os.path.join(images_dir,name) for name in self.names]
self.masks_fps = [os.path.join(masks_dir, name.split(".")[0]+".npy") for name in self.names]
self.transform=transform
def __len__(self):
return len(self.ids)
def __getitem__(self, i):
per_image=Image.open(self.images_fps[i])
per_mask=np.load(self.masks_fps[i])
per_mask[per_mask>self.class_num-1]=0
per_image=self.transform(per_image)
return per_image,per_mask
可以明顯的看出這是一個sequence。