1

I'm only just starting to actually dabble seriously in Python, so it's possible this has a very easy answer, but at the moment I'm just dumbfounded. Here's the gist of what my code is:

class deck:
    cards = [
        'ace of spades',
        'two of spades',
        'three of spades',
    ] #...and so on


    def deal(self, hand): #takes the last card in the deck and transfers it to the supplied hand
        hand.add_card(self.cards.pop(-1))

class hand:
    cards = []

    def add_card(self, card):
        self.cards.append(card)

foobar = deck()
hand1 = hand()
hand2 = hand()
foobar.deal(hand1)
print(hand2.cards) #['three of spades']

What I want is to be able to deal a card from the deck to a hand, by calling deck.deal(hand).

The good news is, the above code does indeed take a card from foobar and add it to hand1. The bad news is... it also adds it to hand2.

This is probably the most confused I've ever been from programming. hand1 and hand2 are quite clearly two distinct variables! So why does dealing a card to one hand also deal the same card to the other hand? I mean, the only time hand2 is even mentioned is when it's being created.

  • possible duplicate of [python class attribute](http://stackoverflow.com/questions/2923579/python-class-attribute) – Cody Piersall Sep 17 '15 at 21:26
  • Actually, more a duplicate of http://stackoverflow.com/questions/207000/python-difference-between-class-and-instance-attributes. It might help you to check out the answers to the linked question, Cal. – Cody Piersall Sep 17 '15 at 21:27
  • first you need to learn the difference between a class and an object. You are using classes as if they were objects. You need to instantiate the classes and create objects for the deck(s) and the hand(s). Pythonwise, `cards`, as they appear in both classes, are class attributes, not instance attributes – Pynchia Sep 17 '15 at 21:29

2 Answers2

2

Your problem is that you wrote cards = [] in the body of your hand class. This makes it a class variable, which is shared between all instances of the class (in your case, hand1 and hand2 are two different instances of the hand class). If any instance changes it, it will be reflected automatically in all other instances.

To create an instance variable in a class, which belongs to a single instance only, you should instead create a constructor inside your hand class which initializes self.cards like this:

def __init__(self):
    self.cards = []

An accessible introduction to instance and class variables is available in the Object-Oriented Programming (subsection "Instance Variables") and Class and Instance Variables chapters at Python Course. The official documentation regarding class and instance variables is in sections 9.3.2 and 9.3.3, respectively, of the Python documentation.

D Coetzee
  • 789
  • 5
  • 5
  • 1
    This is because the code in the body is executed at class definition, not at object instantiation, so the object is created only once (then then shared between all instances) – Ikke Sep 17 '15 at 21:31
1

You need to create an instance variable, not a class variable:

class hand:
    def __init__(self):
        self.cards = []
AChampion
  • 29,683
  • 4
  • 59
  • 75