Python似乎将实例属性视为类属性

时间:2019-04-16 12:47:52

标签: python class attributes instance

我想在此开头说一下,我是Python的新手,并且通常对代码进行编码,因此很可能我错误地使用了一些术语。我正在尝试使用Python制作纸牌游戏“爆炸小猫”的基本版本。我试图将卡片组(没有小猫,要避免抓取的卡片)中的牌分配给类别为Player的每个对象的“属性”实例属性,然后将其从卡片组中删除。我的问题是,如果没有看起来像类属性的作用,我就无法动手处理实例属性。我的代码和结果显示在下面:

import random

# Deck without kittens to deal out to the Players
deck_no_kittens = ["Attack","Attack","Attack","Attack","Steal","Steal","Steal","Steal","Favor","Favor","Favor","Favor","See the future","See the future","See the future","See the future","See the future","Alter the future","Alter the future","Shuffle","Shuffle","Shuffle","Shuffle","Skip","Skip","Skip","Skip"]

# Default starting hand for each player
start_hand = ["Defuse"]

class Player():
  def __init__(self, hand, alive, knowskitten):
    # Hand of each Player
    self.hand = hand
    # Determines if Player is alive
    self.alive = True
    # Determines if the Player knows if there is a kitten
    self.knowskitten = False

# Defines function that deals to Player while also removing it from deck_no_kittens
def deal(player):
  random_index = random.randint(0,len(deck_no_kittens)-1)
  card_to_add = deck_no_kittens.pop(random_index)
  player.hand.append(card_to_add)

# Initialize objects
computer1 = Player(start_hand, True, False)
computer2 = Player(start_hand, True, False)
user = Player(start_hand, True, False)

# Below is where my issue seems to be - the hand remains the same throughout each deal

# Deals 5 times, alternating, to computer1 and computer2, and prints the hand each time
for i in range(5):
  deal(computer1)
  print("\ncomputer1 hand is "+str(computer1.hand))
  deal(computer2)
  print("\ncomputer2 hand is"+str(computer2.hand))

# Prints deck_no_kittens
print("\n"+str(deck_no_kittens))

结果:

computer1 hand is ['Defuse', 'Attack']

computer2 hand is['Defuse', 'Attack', 'Skip']

computer1 hand is ['Defuse', 'Attack', 'Skip', 'See the future']

computer2 hand is['Defuse', 'Attack', 'Skip', 'See the future', 'Steal']

computer1 hand is ['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip']

computer2 hand is['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip', 'Attack']

computer1 hand is ['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip', 'Attack', 'Attack']

computer2 hand is['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip', 'Attack', 'Attack', 'Shuffle']

computer1 hand is ['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip', 'Attack', 'Attack', 'Shuffle', 'Favor']

computer2 hand is['Defuse', 'Attack', 'Skip', 'See the future', 'Steal', 'Skip', 'Attack', 'Attack', 'Shuffle', 'Favor', 'Shuffle']

['Attack', 'Steal', 'Steal', 'Steal', 'Favor', 'Favor', 'Favor', 'See the future', 'See the future', 'See the future', 'See the future', 'Alter the future', 'Alter the future', 'Shuffle', 'Shuffle', 'Skip', 'Skip']

我希望每个对象的手牌都不同,但是每笔交易都增加了通用手牌。任何帮助/建议表示赞赏。

2 个答案:

答案 0 :(得分:0)

两个实例的hand属性都是对同一列表的引用,因此,修改该列表时,它会同时影响这两个列表。

一个简单的解决方法是将列表复制到您班级的__init__

from copy import copy

class Player():
  def __init__(self, hand, alive, knowskitten):
    # Hand of each Player
    self.hand = copy(hand)
    # Determines if Player is alive
    self.alive = True
    # Determines if the Player knows if there is a kitten
    self.knowskitten = False

答案 1 :(得分:0)

这里的问题是您使用相同的“对象” start_hand创建两个玩家。 您将对相同列表start_hand的引用存储在内部变量hand中。

当您在一个播放器中对hand进行修改时,其他播放器可以看到它。

要解决此问题,请创建一个新列表。

self.hand = list(start_hand)