Question

I am messing around building a deck of cards. I have an issue where I have read that eval(repr(object)) should be equivalent to the object stack overflow topic.

I implemented two classes for my cards, a Card class and a Deck class. Each has a repr method in which I attempted to keep as close to the syntax of actually creating the object. Code for init and repr of Card and Deck:

class Card(object):

    def __init__(self, num, suit):
        self.__num = num
        self.__suit = suit

    def __repr__(self):
        return "{!r}({!r},{!r})".format(self.__class__, self.__num, self.__suit)

class Deck(object):

    def __init__(self, cards=None):
        if not cards:
            self.__cards = {"diamonds":[], "hearts":[], "spades":[], "clubs":[]}
        else:
            self.__cards = cards

    def __repr__(self):
         return "{!r}({!r})".format(self.__class__, self.__dict__)

and here is the error:

print(eval(repr(self.deck.deck)))
File "<string>", line 1
{'hearts': [<class 'cards.Card'>(1,'hearts'), <class 'cards.Card'>(2,'hearts'), <class 'cards.Card'>(3,'hearts'), <class 'cards.Card'>(4,'hearts'), <class 'cards.Card'>(5,'hearts')], 'clubs': [<class 'cards.Card'>(1,'clubs'), <class 'cards.Card'>(2,'clubs'), <class 'cards.Card'>(3,'clubs'), <class 'cards.Card'>(4,'clubs'), <class 'cards.Card'>(5,'clubs')], 'spades': [<class 'cards.Card'>(1,'spades'), <class 'cards.Card'>(2,'spades'), <class 'cards.Card'>(3,'spades'), <class 'cards.Card'>(4,'spades'), <class 'cards.Card'>(5,'spades')], 'diamonds': [<class 'cards.Card'>(1,'diamonds'), <class 'cards.Card'>(2,'diamonds'), <class 'cards.Card'>(3,'diamonds'), <class 'cards.Card'>(4,'diamonds'), <class 'cards.Card'>(5,'diamonds')]}
            ^
SyntaxError: invalid syntax

I am simply guessing that it is because of how the Card class is represented. I attempted substituting {!r} for {!s} but it didn't change it. I was considering just hard coding the fact that it is of the class Card in there, but I was hoping there would be some specific way I am meant to do it.

To solve: Just needed to add .__name__ after the self.__class__ and use {!s} (so as to remove the quotes) rather that {!r}

Was it helpful?

Solution

As you can see, your repr is not at all the form used to create the object. It is <class 'cards.Card'>(1,'hearts'), not Card(1, 'hearts'). One way to fix this would be to use self.__class__.__name__ in your __repr__ instead of just self.__class__.

However, why are you doing this? Are you just using eval(repr(...)) to test that the repr is good? There are better ways to create a duplicate of an instance than using eval(repr(...)).

OTHER TIPS

Don't repr the class itself, use its name.

def __repr__(self):
    return "{}({!r},{!r})".format(self.__class__.__name__, self.__num, self.__suit)

It should then look like what it looks like in source code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top