【问题标题】:How to append class object to list如何将类对象附加到列表
【发布时间】:2015-11-14 15:32:58
【问题描述】:

在实例化一副牌 (deck = Deck()) 后,调用 deck.show_deck() 只会打印出“两个菱形”52 次。 “复制”部分与this answer 一致,但似乎没有帮助。有什么建议吗?

import copy
from card import Card

class Deck:

    card_ranks = ['ace','king','queen','jack','ten','nine','eight','seven','six','five','four','three','two']
    card_suites = ['clubs','hearts','spades','diamonds']

    deck = []   

    def __init__(self):
        #create a deck of 52 cards

        for suite in Deck.card_suites:
            for rank in Deck.card_ranks:
                Deck.deck.append(copy.deepcopy(Card(card_rank=rank, card_suite=suite)))



    def show_deck(self):
        for item in Deck.deck:
            print item.get_name()

卡片:

class Card:

    card_name = ''

    def __init__(self, card_rank, card_suite):
        self.card_rank = card_rank.lower()
        self.card_suite = card_suite.lower()
        Card.card_name = card_rank + " of " + card_suite

    def get_name(self):
        return Card.card_name

【问题讨论】:

  • 我会先创建一个包含所有卡片的临时列表,然后将临时列表深度复制到deck
  • 这个临时列表会进入 init 吗?
  • 您没有在此处显示您的Card 代码,但为什么需要deepcopy,尤其是在您第一次实例化它的情况下?这里有点不对劲。
  • 卡片比较琐碎,我这里补充一下
  • @user2372996 是的,临时列表将进入__init__,但我不禁认为这里存在设计问题,因为你真的不应该在这里需要深拷贝。至于为什么您问题中的代码不起作用的原因,我现在只是想弄清楚。

标签: python list class object append


【解决方案1】:

这里的问题是Card 类有一个名称变量,它与Card 类的所有实例共享。

当你有:

class Card:

    card_name = ''

这意味着所有 Card 对象都将具有相同的名称 (card_name),这几乎肯定不是您想要的。

您必须像这样使名称成为实例的一部分:

class Card:
    def __init__(self, card_rank, card_suite):
        self.card_rank = card_rank.lower()
        self.card_suite = card_suite.lower()
        self.card_name = card_rank + " of " + card_suite

    def get_name(self):
        return self.card_name

你会发现deepcopy 不需要,也从来不需要,但它确实告诉你deepcopy 不允许你保持类变量的不同状态。

此外,如果您想将其打印出来,我建议您将 Card 更改为拥有自己的 __str__ 方法:

class Card:
    def __init__(self, card_rank, card_suite):
        self.card_rank = card_rank.lower()
        self.card_suite = card_suite.lower()

    def __str__(self):
        return "{0} of {1}".format(card_rank, card_suit)

这使用 Python 语言本身来打印类,并且有一个好处是您的类现在可以在打印语句和转换为字符串时正常工作。所以而不是:

print some_card.get_name()

你可以的

print some_card

【讨论】:

  • 领先我 30 秒。更好的是:u'%s of %s' % (card_rank, card_suit)(只要你把它到处改成card_suit)。
  • 在这里我认为Card 是微不足道的......非常感谢你
【解决方案2】:

扩展shuttle87所说的:

class Card:

    card_name = ''

使card_name 成为静态变量(在该类的所有实例之间共享)

一旦您将变量设为非静态变量(通过在 __init__ 方法中使用 self.card_name),您就不必担心复制部分,因为卡片类的每个实例都有自己唯一的名称

请注意,Deck 中的 deck 在您的代码中也是静态的。

from card import Card

class Deck:
    # these 2 can be static, they never change between copies of the deck class
    card_ranks = ['ace','king','queen','jack','ten','nine','eight','seven','six','five','four','three','two']
    card_suites = ['clubs','hearts','spades','diamonds']

    def __init__(self):
        # this shouldn't be static since you might want to shuffle them 
        # or do other things that make them unique for each deck
        self.cards = []

        for suite in Deck.card_suites:
            for rank in Deck.card_ranks:
                self.cards.append(Card(rank, suite))

    def show_deck(self):
        for item in self.cards:
            print item

class Card:
    def __init__(self, rank, suite):
        self.rank = rank
        self.suite = suite

    def __str__(self):
        return self.rank + ' of ' + self.suite

#! python2

from deck import Deck

def main():
    deck = Deck()

    deck.show_deck()

if __name__ == '__main__':
    main()

ace of clubs
king of clubs
queen of clubs
jack of clubs
...

【讨论】:

  • 我不相信副本实际上会帮助解决存储在类变量中的状态问题,我认为您通过提及这一点来解决一个重要的值得支持的答案部分,所以您可能希望来测试一下。此外,要在答案文本中格式化代码内联,您可以使用反引号。
  • 感谢格式帮助。我测试了上面的代码(从我电脑上的源文件复制)
猜你喜欢
  • 1970-01-01
  • 2021-12-10
  • 2020-12-19
  • 2022-01-22
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多