如何使用__str__方法打印列表?

时间:2018-12-06 14:43:27

标签: python string class oop methods

class Deck:

    def __init__(self):
        self.cards=[]
        for suit in range(4):
            for rank in range(1,14):
                card=Card( suit, rank )
                self.cards.append(card)

    def __str__ (self):
        res=[]
        for card in self.cards:
            res.append(str(card))

        return '\n'.join(res)

    def pick_card(self):
        from random import shuffle
        shuffle(self.cards)
        return self.cards.pop()

    def add_card(self,card):
        if isinstance(card, Card): #check if card belongs to card Class!!
            self.cards.append(card)

    def move_cards(self, gen_hand, num):
        for i in range(num):
            gen_hand.add_card(self.pick_card())


class Hand(Deck):

    def __init__(self, label=''):
        self.cards = []
        self.label = label

    def __str__(self):
        return 'The {} is composed by {}'.format(self.label, self.cards)

mazzo_uno = Decks()
hand = Hand('New Hand')
mazzo_uno.move_cards(hand, 5)
print(hand)

我正在尝试学习面向对象的编程。当我尝试从子类Hand()中打印对象 hand 时,出现了这个问题。我打印了类似这样的 << strong> main .Card对象,位于0x10bd9f978> ,而不是self.cards列表中5张卡片的正确字符串名称:

The New Hand is composed by [<__main__.Card object at 0x10bd9f978>, 
<__main__.Card object at 0x10bd9fd30>, <__main__.Card object at 0x10bd9fe80>, 
<__main__.Card object at 0x10bcce0b8>, <__main__.Card object at 0x10bd9fac8>]

我也尝试过这样做以将self.cards转换为字符串,但是我得到了"TypeError: sequence item 0: expected str instance, Card found"

def __str__(self):
    hand_tostr = ', '.join(self.cards)
    return 'The {} is composed by {}'.format(self.label, hand_tostr)

我在该网站上阅读了其他答案,我应该使用__repr__,但我不知道如何在Hand类中添加它。

1 个答案:

答案 0 :(得分:0)

__repr____str__的作用不同,但工作方式相同。

您可以阅读this来帮助您在两种方法之间进行选择。


您可以像这样更改Hand类的__str__方法:

class Hand:

    def __str__(self):
        hand_tostr = ', '.join(map(str, self.cards)) # I use map to apply str() to each element of self.cards
        return 'The {} is composed by {}'.format(self.label, hand_tostr) 

如果要更改Card类的__repr__方法,可以尝试类似的操作(您未提供Card类的代码)

class Card:
    #your code

    def __repr__(self):
        return <some string>

现在,如果您执行str(<list of Card objects>),它将在每个卡实例上使用__repr__方法来显示所需的内容。我不是这种解决方案的忠实拥护者,对于您的情况,我将使用第一个解决方案,因为在其他情况下,您可能希望保留卡片对象的默认表示形式。


请谨慎使用此代码:

def add_card(self,card):
    if isinstance(card, Card): #check if card belongs to card Class!!
        self.cards.append(card)

如果card不是Card的实例,则不会筹集任何资金。这意味着,如果使用错误的参数使用此方法,错误将被隐藏,并且您将不知道卡座没有更改。这很危险。您可以改为执行以下操作:

def add_card(self,card):
    assert(isinstance(card, Card)), "card parameter of add_card must be an instance of Card class"
    self.cards.append(card)

您可以使用typehint以更Python化的方式通知您的类用户Card应该是Card的实例。然后,相信python的鸭子风格,或者使用mypy之类的工具来验证该方法是否正确使用。