python之使用魔术方法__getitem__和__len__
(1)像__getitem__这种由两个双下划线构成的方法,被称为魔术方法。 (2)魔术方法是为了给python解释器用的。当使用len(collection)时,实际上调用的就是collection.__len__方法。而在使用obj[key]的形式来访问元素时,实际上调用的是object.__getitem__(key)方法。 (3)魔术方法是属于类的方法,也就是说不需要实例化类就可以访问到该方法,同时,实例化的对象都可以访问到该方法。 (4)使用__getitem__和__len__方法,我们就可以实现一个对自定义数据类型的迭代和访问。 举个例子: import collections Card = collections.namedtuple("Card",[ranksuit"]) class FrenchDeck(object): ranks = [str(n) for n in range(2,11)] + list(JQKA) #黑桃 方块 红桃 梅花 suits = spades diamonds hearts clubs .split() def __init__(self): self._cards = [Card(rank,suit) for rank in self.ranks for suit self.suits] __getitem__(self,item): return self._cards[item] __len__(self): return len(self._cards) 说明:
首先说明的是类属性和方法,直接用类名.属性或类名.方法访问即可。 print(FrenchDeck.ranks) (FrenchDeck.suits) print(FrenchDeck.__len__(FrenchDeck())) 输出: 自定义的FrenchDeck类在重写了__getitem__和__len__方法之后,就可以对FrenchDeck实例化的对象进行类似于列表的操作。 1.得到对象的长度 deck = FrenchDeck() print(len(deck)) 输出:52 2.通过下标来获列表元素 (deck[0]) print(deck[-1]) 输出: Card(rank='2',suit='spades') 3.对列表进行遍历。当然也可以使用reversed方法进行翻转遍历 for d reversed(deck): print(d) 输出: Card(rank='A',suit='clubs') 4.使用choice随机抽取一张牌 from random choice print(choice(deck)) 5.利用in判断一张牌是否在对象列表中 print(Card(Qclubs") in deck) 6.可以对牌组进行排序,按照花色桃心梅方以及数值大小 def spades_high(card): 首先得到该卡牌在数值中的位置 rank_value = FrenchDeck.ranks.index(card.rank) 返回的是其位置*4+花色对应的级别 比如梅花2的大小为0,黑桃A的大小为12*4+3=51 return rank_value*len(suit_values)+suit_values[card.suit] Card = Card("A","spades") #print(spades_high(Card)) for card in sorted(deck,key=spades_high): print(card) 输出; Card(rank='2',suit='spades') 说了这么多,就是为了说明通过实现__getitem__和__len__方法,FrenchDeck就和一个python自有的序列数据类型一样了。对合成的运用使得__len__和__getitem__的具体实现可以代理给self._card这个python列表。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |