开发者

Python appending to two lists when it should only append to one

I have a list called teams which contains two objects, these are objects of the same class and they both have a "members" list. I am appending to these lists individually. See Fight.AddParticipant开发者_运维知识库 but the two participant objects I'm appending seem to end up in both of the team objects, which is unintended behavior. Why is this happening?

Code:

class Fight:
    participants = []
    teams = []
    attacked = []
    fighting = 0

    def MakeTeams(self, team):
        self.teams.append(team)

    def NumParticipants(self, teamnum = None):
        if (teamnum != None):
            return len(self.teams[teamnum].members)
        else:
            return len(self.participants)


    def AddParticipant(self, participant, team):
        self.participants.append(participant)
        ref = self.participants[-1]
        self.teams[team].members.append(ref)
        # print self.teams[1].members[0].name

    def SetFighting(self):
        self.fighting = self.NumParticipants()

    def AnnounceFight(self):
        print 'A battle between', self.NumParticipants(), 'fighters has begun!\n\n'
        self.AnnounceTeams()

    def AnnounceTeams(self):
        print ''
        for team in self.teams:
            print "Team name:", team.name
            print "Team morale:", team.morale
            for member in team.members:
                print member.name


class Participant:
    name = ""
    race = ""
    sex = ""
    hp = 0
    strength = 0
    agility = 0
    weapon = ""
    alive = True

    def __init__(self, name, race, sex, hp, strength, agility, weapon, alive = True):
        self.name = name
        self.race = race
        self.sex = sex
        self.hp = hp
        self.strength = strength
        self.agility = agility
        self.weapon = weapon
        self.alive = alive


class Team:
    name = ""
    members = []
    morale = 0

    def __init__(self, name, morale):
        self.name = name
        self.morale = morale

Fight = Fight()
Fight.MakeTeams(Team('Smart', 1))
Fight.MakeTeams(Team('Dumb', 1))
Fight.AddParticipant(Participant("Foo", "Human", "Female", 15, 15, 20, "Knife"), 0)
Fight.AddParticipant(Participant("Bar", "Human", "Male", 15, 15, 20, "Sabre"), 1)
Fight.SetFighting()
Fight.AnnounceFight()


In all of your classes, you want to initialize instance variables like this:

def __init__(self):
    self.participants = []
    self.teams = []
    self.attacked = []
    self.fighting = 0

That way, they are separate for each fight, participant, team instead of shared for all fights, participants, or teams.


You have made the lists as class attributes, which means the lists are shared by all instances. It's the same list. You should make the lists instance attributes. Do that by creating them in the __init__ (constructor) method of the class.


I think you mean members to be a member of an instance, but instead making them class members. Try this:

class Team:
    name = ""
    morale = 0

    def __init__(self, name, morale):
        self.members = []
        self.name = name
        self.morale = morale

You probably want to move all the other variables into constructors rather than keeping them as class variables. Class variables are shared by all instances and owned by class.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜