Search code examples
pythonclassrepr

__repr__ and python unpacking


I am attempting to print a players hand in a python project using classes.

(after much frustration I googled how do to this with unpacking)

is anyone able to provide an example of how I could use __repr__ to simply print this list? instead of __init__ can this be exchanged for __repr__ ? is there another function that should be used to add the ability to print a list from a class?

for examples, why does the below work with unpacking but does not work without?

>>> 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>]

the main body of my code is below:

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())

Solution

  • Define a __repr__ in your Card class:

    def __repr__(self):
        return str(self)
    

    and then your Deck can simply do:

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

    When you call str() with a list, it will call repr() for the individual elements of the list and format them with the familiar [foo, bar, baz] formatting.