【问题标题】:__repr__ and python unpacking__repr__ 和 python 解包
【发布时间】:2020-09-13 23:53:09
【问题描述】:

我正在尝试使用类在 python 项目中打印玩家手。

(在经历了很多挫折之后,我用谷歌搜索了如何通过拆包来做到这一点)

有没有人能提供一个例子来说明我如何使用__repr__ 来简单地打印这个列表?而不是__init__ 可以换成__repr__ 吗?是否应该使用另一个函数来添加从类中打印列表的功能?

例如,为什么下面的解包可以工作,但没有解包就不行?

>>> print(*test_player.cards, sep='\n')
Ace of Clubs
King of Clubs
>>> print(test_player.cards)
[<__main__.Card object at 0x000001E2BA608388>, <__main__.Card object at 0x000001E2BA608488>]

我的代码主体如下:

suits = ('Hearts', 'Diamonds', 'Spades', 'Clubs')
ranks = ('Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight', 'Nine', 'Ten', 'Jack', 'Queen', 'King', 'Ace')
values = {'Two':2, 'Three':3, 'Four':4, 'Five':5, 'Six':6, 'Seven':7, 'Eight':8, 
            'Nine':9, 'Ten':10, 'Jack':10, 'Queen':10, 'King':10, 'Ace':11}
class Card:

    def __init__(self,suit,rank):
        self.suit = suit
        self.rank = rank

    def __str__(self):
        return self.rank + ' of ' + self.suit


class Deck:

    def __init__(self):
        self.deck = []  # start with an empty list
        for suit in suits:
            for rank in ranks:
                self.deck.append(Card(suit,rank))

    def __str__(self):
        deck_comp = ''  # start with an empty string
        for card in self.deck:
            deck_comp += '\n '+card.__str__() # add each Card object's print string
        return 'The deck has:' + deck_comp

    def shuffle(self):
        random.shuffle(self.deck)

    def deal(self):
        single_card = self.deck.pop()
        return single_card


class Hand:

    def __init__(self):
        self.cards = []  # start with an empty list as we did in the Deck class
        self.value = 0   # start with zero value
        self.aces = 0    # add an attribute to keep track of aces


    def add_card(self,card):
        self.cards.append(card)
        self.value += values[card.rank]

test_player=Hand()
test_deck=Deck()
test_player.add_card(test_deck.deal())
test_player.add_card(test_deck.deal())

【问题讨论】:

  • 列表中的项目将使用__repr__ 打印,这就是您的第二个示例中发生的情况。如果你真的想改变这个,覆盖__repr__Card。 (我不推荐它,因为它违背了打印列表的标准 Python 方式。相反,可能覆盖 __str__ 为您打印卡片的 Hand,或添加 print_cards() 函数到 Hand) .

标签: python class repr


【解决方案1】:

Card 类中定义 __repr__

def __repr__(self):
    return str(self)

然后你的Deck 可以简单地做:

def __str__(self):
    return str(self.deck)

当您使用列表调用 str() 时,它将为列表中的各个元素调用 repr(),并使用熟悉的 [foo, bar, baz] 格式对其进行格式化。

【讨论】:

    【解决方案2】:

    当你打印一个列表时,它的 repr 包括每个元素的 repr,所以为你的 Card 类创建一个 __repr__ 方法。 The __repr__ method should show info you can use for debugging,如果它显示了如何构造对象就更好了,所以我会使用这个:

    def __repr__(self):
        return f'{type(self).__name__}({self.suit!r}, {self.rank!r})'
    

    所以现在我们得到了这个:

    >>> print(test_player.cards)
    [Card('Clubs', 'Ace'), Card('Clubs', 'King')]
    

    我还会在Deck 中添加一个__repr__,虽然我们无法展示它的构造,所以我会使用这个:

    def __repr__(self):
        return f'<{type(self).__name__}: deck={self.deck!r}>'
    

    为了简单起见,现在我只得到最后两个元素,然后检查 repr:

    >>> test_deck.deck = test_deck.deck[-2:]
    >>> test_deck
    <Deck: deck=[Card('Clubs', 'Jack'), Card('Clubs', 'Queen')]>
    

    你可以对Hand 使用类似的东西:

    def __repr__(self):
        return f'<{type(self).__name__}: cards={self.cards!r}>'
    
    >>> test_player
    <Hand: cards=[Card('Clubs', 'Ace'), Card('Clubs', 'King')]>
    

    顺便说一句,您可以考虑让Deck 继承自list 以避免有点笨拙的Deck.deck,并让它直接支持索引等。

    【讨论】:

      猜你喜欢
      • 2011-12-07
      • 1970-01-01
      • 2018-11-23
      • 2021-12-06
      • 2013-01-20
      • 2014-05-03
      • 2011-05-07
      • 2022-01-13
      相关资源
      最近更新 更多