2

我正在乱搞一副牌。我有一个问题,我读过 eval(repr(object)) 应该等同于对象堆栈溢出主题

我为我的卡片实现了两个类,一个 Card 类和一个 Deck 类。每个都有一个 repr 方法,我试图在该方法中尽可能接近实际创建对象的语法。Card and Deck的init和repr代码:

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

这是错误:

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

我只是猜测这是因为 Card 类的表示方式。我试图用 {!r} 代替 {!s} 但它并没有改变它。我只是在考虑硬编码它属于 Card 类的事实,但我希望有一些特定的方式可以做到这一点。

解决:只需要在.__name__后面加上self.__class__并使用 {!s} (以便删除引号)而不是 {!r}

4

2 回答 2

4

如您所见,您repr的表单根本不是用于创建对象的表单。它是<class 'cards.Card'>(1,'hearts'),不是Card(1, 'hearts')。解决此问题的一种方法是self.__class__.__name__在您的__repr__而不是仅使用self.__class__.

然而,你为什么要这样做?你只是eval(repr(...))用来测试repr好不好?有比使用更好的方法来创建实例的副本eval(repr(...))

于 2013-01-02T02:07:32.213 回答
2

不要代表类本身,使用它的名称。

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

然后它应该看起来像它在源代码中的样子。

于 2013-01-02T02:07:49.270 回答