专业编程基础技术教程

网站首页 > 基础教程 正文

如何用扑克牌程序来理解Python中的__getitem__()和__len__()

ccvgpt 2024-08-10 12:49:57 基础教程 13 ℃

流畅的Python学习笔记

通过代码可以理解__len__()和__getitem__的功能。

如何用扑克牌程序来理解Python中的__getitem__()和__len__()

在Python中,会使用特殊方法激活一些基本的对象操作,这些特殊方法用两个下划线开头。

比如len(obj)其实是调用了obj.__len__()

而obj[key]是调用了obj.__getitem__(key)

下面的例子来帮助理解这些特殊方法的用法。

import collections
Card = collections.namedtuple('扑克牌',['数字','花色'])
class FrenchDeck:
    ranks = [str(n) for n in range(2,11)] + list('JQKA')
    suits = '? ? ? ?'.split()
    def __init__(self):
        self._cards = [Card(rank,suit) for suit in self.suits for rank in self.ranks]
        
    def __len__(self):
        return len(self._cards)
    
    def __getitem__(self,pos):
        return self._cards[pos]   
    
    def set_card(self,pos,card):
        self._cards[pos] = card
        
    def __setitem__(self,pos,card):
        return self.set_card(pos,card)

collections.namedtuple()命名元组赋予每个位置一个含义,提供可读性和自文档性。它们可以用于任何普通元组,并添加了通过名字获取值的能力,通过索引值也是可以的。

我们知道元组访问方式一般是 元组名[0] 这样的。但是namedtuple赋予元组另一种通过名称获取值的能力。如下:

beer_card = Card('7','?')
print('beer_card[0] =',beer_card[0])    #一般元组访问方式
print('beer_card.数字 =',beer_card.数字)     #用了namedtuple方法后可以使用key访问
输出为:
beer_card[0] = 7
beer_card.数字 = 7

获得一共有多少扑克,其实是调用了__len__()方法。
因此以下的2个代码是一样的。

deck = FrenchDeck()
print(len(deck))
print(deck.__len__())
输出为:
52
52

获得第一个元素和最后一个元素,和一般对序列的操作一样。

deck[0]
输出为:
扑克牌(数字='2', 花色='?')

deck[-1]
输出为:
扑克牌(数字='A', 花色='?')

随机抽取一张扑克牌,使用了 random的choice
每次都是随机抽取

from random import choice
choice(deck)
输出为:扑克牌(数字='5', 花色='?')
choice(deck)
输出为:扑克牌(数字='7', 花色='?')

查看最上面3张牌都是什么?

deck[:3]
输出为:
[扑克牌(数字='2', 花色='?'), 扑克牌(数字='3', 花色='?'), 扑克牌(数字='4', 花色='?')]

查看数字为A的全部牌,其实操作是先取得索引是12的牌,
2-10 9张 JQK 3张 A为第13张,因为索引从0开始因此是12。 之后每13张牌取1张。

deck[12::13]
输出为:
[扑克牌(数字='A', 花色='?'),
 扑克牌(数字='A', 花色='?'),
 扑克牌(数字='A', 花色='?'),
 扑克牌(数字='A', 花色='?')]

因为__getitem__方法,所以deck对象可以迭代。因此我们使用for循环来顺序获得所有的牌。

for card in deck: 
    print(card)

一般 contains 方法可以实现成员检查的操作,如果没有的话 in 运算符按顺序做迭代搜索。

Card('4','?') in deck
输出为:
True

我们也可以进行洗牌操作,需要 random 的 shffle方法。

from random import shuffle
deck=FrenchDeck()
shuffle(deck)
deck[:5]

Tags:

最近发表
标签列表