大家可能很熟悉在collections模塊中有一個很好用的擴展數據類型-namedtuple。
如果你還不知道這個類型,那么請翻看標準手冊。
先把代碼貼上,滿足心急的朋友。
def myNamedTuple(tuple_name, attrs_str): attrs_set = set(attrs_str.split(' ')) def __init__(self, attrs): #我們將來實例初始化的時候需要調用的方法。 for key, value in zip(attrs_set, set(attrs)): self.__dict__[key]=value def __str__(self): #這個只是方便打印用的。 values = [str(x) for x in self.__dict__.values()] return tuple_name+'(' + ', '.join(values) + ')' def to_dict(self): #提供一個to_dict()方法,用來把我們的命名元組轉為字典。 return self.__dict__ #調用type來建立類。 #第二個參數指定其繼承自元組。 #第三個參數指定我們需要存入的屬性名(也就是__dict__的鍵名,然后就是上面定義的方法。 return type(tuple_name, (tuple,),{'attr_keys':attrs_set,'__init__':__init__,'__str__':__str__,'to_dict':to_dict})if __name__=='__main__': Point = myNamedTuple('Point','x y') p = Point([1,2]) #目前我們的參數只能傳入一個,否則報錯,這是和namedtuple之間的差別。 PRint(p) print(type(Point),p, sep='/n') print(p.x,'---',p.y) print(p[0],p[1]) print(p.to_dict) p +=(4,) #此時已經變成了普通的tuple了。內置的namedtuple也是一樣。 print(type(Point),p, sep='/n')其實,Python的內部也是創建了一個繼承自tuple的類。
>>> from collections import namedtuple>>> Rectangle=namedtuple('Rectangle', 'height width')>>> r = Rectangle(3,4)>>> type(r)<class '__main__.Rectangle'>建立一個列表用來存儲所有需要存入的健。在將來實例化調用__init__方法的時候,我們再來建立實例的__dict__屬性字典。
至于取值,那么就是類調用實例的__dict__了。
如果看不明白的,請先看我關于元類介紹的那一講。
由于我們的類繼承自元組,而元組默認只能傳入一個可迭代對象。
那么我們修改一下原來的代碼,讓我們的myNamedTuple也可以像namedtuple一樣可以接受多個參數。
def myNamedTuple(tuple_name, attrs_str): class Meta(type): #定義一個元類,采用`__call__`方法來攔截類的實例化,在實例化之前我們先把位置參數全部轉入一個叫args的元組中,然后在調用type的`__call__`方法,從而把剛才的元組傳進去,這樣就只有一個參數了,從而無論你傳入多少個位置參數,在這個步驟之后,只會出現一個參數了,成功! def __call__(self, *args): return type.__call__(self, args) attrs_set = set(attrs_str.split(' ')) def __init__(self, args): for key, value in zip(attrs_set, set(args)): self.__dict__[key]=value def __str__(self): values = [str(x) for x in self.__dict__.values()] return tuple_name+'(' + ', '.join(values) + ')' def to_dict(self): return self.__dict__ return Meta(tuple_name, (tuple,),{'attr_keys':attrs_set,'__init__':__init__,'__str__':__str__,'to_dict':to_dict})if __name__=='__main__': Point = myNamedTuple('Point','x y') print(Point) p = Point(1,2) #多個參數成功調用.... print(p) print(type(Point),p, sep='/n') print(p.x,'---',p.y) print(p[0],p[1]) print(p.to_dict) p +=(4,) #此時已經變成了普通的tuple了。 print(type(Point),p, sep='/n')如果有什么不懂的,請留言。
如果這個例子通了,那么collections中的其他數據類型是不是也是一樣的道理呢?
新聞熱點
疑難解答