Inexplicable behavior in simple example of a set in a class

Peter Otten __peter__ at web.de
Sun Jul 3 00:22:32 CEST 2011


Saqib Ali wrote:

> 
> 
> I have written two EXTREMELY simple python classes. One class
> (myClass1) contains a data attribute (myNum) that contains an integer.
> The other class (myClass2) contains a data attribute (mySet) that
> contains a set.
> 
> I instantiate 2 instances of myClass1 (a & b). I then change the value
> of a.myNum. It works as expected.

self.value = new_value

sets the attribute to a new value while

self.value.modifying_method()

keeps the old value (the object with the same id(object)), but changes the 
state of that old object. All variables bound to that object will "see" that 
internal change of state. As integers are "immutable" objects whose state 
cannot be changed you'll never observe the behaviour described below with 
them.

> Then I instantiate 2 instances of myClass2 (c & d). I then change the
> value of c.mySet. Bizarrely changing the value of c.mySet also affects
> the value of d.mySet which I haven't touched at all!?!?! Can someone
> explain this very strange behavior to me? I can't understand it for
> the life of me.

What you access as c.mySet or d.mySet is really myClass2.mySet, i. e. a 
class attribute and not an instance attribute. If you want a set per 
instance you have to create it in the __init__() method:

>>> class MyClass:
...     def __init__(self):
...             self.my_set = set(range(10))
...     def clear_set(self):
...             self.my_set.clear()
...
>>> a = MyClass()
>>> b = MyClass()
>>> a.my_set.add(42)
>>> a.my_set, b.my_set
(set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42]), set([0, 1, 2, 3, 4, 5, 6, 7, 8, 
9]))
>>> b.clear_set()
>>> a.my_set, b.my_set
(set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 42]), set([]))




More information about the Python-list mailing list