0

I am new to Python so this might be a very dull question, though I have searched a lot on the subject and could not find an answer.

So I am trying to code a simple "card game", and for that defined a class "Player", containing the list attribute "cards". I have made sure this attribute is within "def init" so that it is specific to the class instance, however when I append an element to this list for a Player A, it also appends it for Player B. Note: my code also includes a class "Deck" and "Card" that I do not explicitate here to keep it light)

class Player(object): #defines Player class, including its score and name
    all_players=[]
    def __init__(self,score,name,cards=[]):
        self.score=score
        self.name=name
        self.cards=cards
        Player.all_players.append(name)

playera=Player(0,'John')
playerb=Player(0,'Bill')
playera.cards.append(Deck.hidden_cards[0])

==> playera.show_cards() and playerb.show_cards() then print the same results

If someone could help me on that it would be much appreciated ! Thanks in advance.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Gregeuhar
  • 3
  • 1

1 Answers1

1

The error is because of this line: def __init__(self,score,name,cards=[]): - because of cards=[]. For mutable types in methods (like the empty list), it's the same list that gets shared among different instances. Initialize with None and assign it an empty list inside __init__.

class Player(object):
    all_players = []
    def __init__(self, score, name, cards=None):
        if cards is None:
            self.cards = []
        ...etc.

Edit: See @BradBudlong's comment below for a better explanation about the handling of default parameters.

Community
  • 1
  • 1
aneroid
  • 12,983
  • 3
  • 36
  • 66
  • 2
    The problem is very specific to the handling of default parameters. If you hadn't used the default parameter you wouldn't have had this problem: `playera=Player(0,'John',[])`. The default parameters get evaluated when the function is defined. That causes this default value of an empty list to be created and this same list to be assigned each time that the parameter is not provided. If in your example you tested whether they were the same list it would say they are: `playera.cards is playerb.cards` returns `True` – Brad Budlong Apr 26 '14 at 19:14
  • +1 Yup, I should have been more specific that it's about how default parameters are handled. Couldn't find the SO answer with that exact explanation. – aneroid Apr 26 '14 at 19:17