国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Python元類實踐--自己定義一個和collections中一樣的namedtuple

2019-11-14 17:02:44
字體:
來源:轉載
供稿:網友

大家可能很熟悉在collections模塊中有一個很好用的擴展數據類型-namedtuple。
如果你還不知道這個類型,那么請翻看標準手冊。

我利用元類輕松定義一個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中的其他數據類型是不是也是一樣的道理呢?


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 清河县| 浏阳市| 罗田县| 阜新市| 荥经县| 海门市| 花莲市| 肥乡县| 基隆市| 广安市| 原阳县| 博白县| 耿马| 高清| 沂南县| 昌平区| 甘谷县| 连云港市| 新巴尔虎右旗| 河西区| 金溪县| 象州县| 家居| 孝义市| 乐山市| 中江县| 马龙县| 裕民县| 三河市| 五峰| 伊宁县| 宁南县| 吉首市| 九江市| 苗栗市| 团风县| 安陆市| 辉县市| 东山县| 南平市| 石楼县|