So you’ve just created your first class in Python, a neat little class that encapsulates a playing card:

class Card:
    def __init__(self, suit, pips):
        self.suit = suit
        self.pips = pips

Elsewhere in your code, you create a few instances of this class:

ace_of_spades = Card('Spades', 1)
four_of_clubs = Card('Clubs',  4)
six_of_hearts = Card('Hearts', 6)

You’ve even created a list of cards, in order to represent a “hand”:

my_hand = [ace_of_spades, four_of_clubs, six_of_hearts]

Now, during debugging, you want to see what your hand looks like, so you do what comes naturally and write:

print(my_hand)

But what you get back is a bunch of gibberish:

[<__main__.Card instance at 0x0000000002533788>, 
 <__main__.Card instance at 0x00000000025B95C8>, 
 <__main__.Card instance at 0x00000000025FF508>]

Confused, you try just printing a single card:

print(ace_of_spades)

And again, you get this weird output:

<__main__.Card instance at 0x0000000002533788>

Have no fear. We’re about to fix this.

First, however, it’s important to understand what’s going on here. When you wrote print(ace_of_spades) you told Python you wanted it to print information about the Card instance your code is calling ace_of_spades. And to be fair, it did.

That output is comprised of two important bits: the [type](<https://docs.python.org/3/library/functions.html#type>) of the object and the object’s [id](<https://docs.python.org/3/library/functions.html#id>). The second part alone (the hexidecimal number) is enough to uniquely identify the object at the time of the print call.[1]

What really went on was that you asked Python to “put into words” the essence of that object and then display it to you. A more explicit version of the same machinery might be:

string_of_card = str(ace_of_spades)
print(string_of_card)

In the first line, you try to turn your Card instance into a string, and in the second you display it.