0

I've noticed something I'm confused about when creating member variables of a class, then setting their value in a class method. Essentially, in my program whenever I change both member variables in this function, they both change like they're supposed to. However, when I create any other instance of that class without calling the method that changes those member variables, only one stays the same.

class Game(object):
     isGoing=True
     board=[1,2,3]


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

     def test(self):
         self.board[0]="X"
         self.isGoing=False


 t1=Game("Testing")
 t1.test()
 print t1.isGoing
 print t1.board

 t2=Game("Testing")
 print t2.isGoing
 print t2.board

This will end up printing:

False

['X',2,3]

True

['X',2,3]

My question is, why did only the isGoing member variable revert back to True, and the board list stayed the same as it was?

1 Answers1

1

This is because you have assigned board to the class Game, rather than individual instances via the __init__ method of the class, resulting in every instances of Game sharing the same Game.board attribute. To ensure every instance have its own independent value __init__ needs to be used:

   def __init__(self, name):
       self.name = name
       self.board = [1, 2, 3]

If you wish to have board be an assignable argument with a potential default value, you will once again fall into a similar pitfall as this issue if you wrote something like

   def __init__(self, name, board=[1, 2, 3]):
       self.name = name
       self.board = board

In fact, both your issue and the other one outlined there is quite similar - this is driven by the fact that Python is an assignment based language, and if a given variable is assigned the same mutable value and its mutation methods are called, all variables assigned that value will see the changes be effected.

Community
  • 1
  • 1
metatoaster
  • 17,419
  • 5
  • 55
  • 66
  • This helps a lot! Thank you very much. However, I'm still a bit new to the language and I have another question. If all instances of the class share the board attribute, would that be applicable to them all sharing the isGoing attribute? And if so, why did only the isGoing attribute go back to being True? – Stephen Landaas Jun 03 '16 at 04:39
  • @StephenLandaas it is the very exact same thing: you have **assigned** `self.isGoing` a new value, and `self` is an instance variable specific to whatever it is. On the otherhand, if you assign `Game.isGoing` a value from somewhere, and then later access that also via `Game.isGoing` from somewhere else (such as a different instance), the original assigned value will be returned. – metatoaster Jun 03 '16 at 06:16
  • Also, getting the attributes of a given `self` will always fall back to its class object (in your case, the constuct created by `class Game`) and its parents until the attribute identified by the specific name (`board`, or `isGoing`) is found and the value assigned there is returned. – metatoaster Jun 03 '16 at 06:20