1

For class A, why is aMap member variable being shared between object and object b?

>>> class A:
...     aMap = {}

>>> a = A()
>>> a.aMap["hello"] = 1

>>> b = A()
>>> b.aMap["world"] = 2

>>> c = []
>>> c.append(a)
>>> c.append(b)

>>> for i in c:
...     for j in i.aMap.items():
...         print j
('world', 2)  
('hello', 1)  
('world', 2)  
('hello', 1)  
Esteban Küber
  • 36,388
  • 15
  • 79
  • 97
bob
  • 1,941
  • 6
  • 26
  • 36
  • I believe http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument explains this. – aem Feb 19 '10 at 21:47
  • possible duplicate of [How do I avoid having Python class data shared among instances?](http://stackoverflow.com/questions/1680528/how-do-i-avoid-having-python-class-data-shared-among-instances) – Martijn Pieters Feb 23 '13 at 15:41

3 Answers3

5

Because you defined it as a class attribute, not instance attribute.

If you wish to have it as instance attribute and not be shared between instances, you have to define it like this:

class A(object):
    def __init__(self):
        self.aMap = {}
gruszczy
  • 40,948
  • 31
  • 128
  • 181
  • +1: Class attributes are shared among objects. Be careful of vague phrases like "member variable". Try to talk about "instance attributes" and "class attributes", not "member variables", which is vague. – S.Lott Feb 19 '10 at 21:48
  • True, especially since it's the only way to use properties, when you need them in the future :-) – gruszczy Feb 19 '10 at 21:50
3

Because its a class attribute, not an instance attribute ("member variable").

To make it a instance attribute, assign it on an instance, e.g. in the constructor:

class A:
    def __init__(self):
        self.aMap = {}

But you could also do:

a = A()
a.aMap = {}
oefe
  • 19,298
  • 7
  • 47
  • 66
0

Because you are effectively defining a class variable instead of an instance variable.

To define an instance variable, you should do it on a method referring the object itself (generally self):

class A(object):
    class_variable = 0

    def __init__(self, a, b):
        self.instance_variable = a
        class_variable = b

>>> a=A(1,2)
>>> print a.instance_variable
1
>>> print a.class_variable
2
>>> b=A(2,1)
>>> print b.instance_variable
2
>>> print b.class_variable
1
>>> print a.instance_variable
1
>>> print a.class_variable
1
Esteban Küber
  • 36,388
  • 15
  • 79
  • 97