1

I have a program in which I intend to compare the contents of a dictionary from two different instances of a class (I intend to make this a routing protocol simulation where FIB tables are compared) and it seems when I update the dictionary in one object, the other has its dictionary updated with the same information.

class bar:
    myName = ""
    mydict1 = {'a': '', 'b': ''}
    mydict2 = {}

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

    def addItem(self, x, y):
        self.mydict2[x] = y

foo = bar('a')

foo.addItem('a', 'test')
print(foo.myName, foo.mydict2)

foo2 = bar('b')
print(foo2.myName, foo2.mydict2)

The output of this is:

a {'a': 'test'}
b {'a': 'test'}

I'm not sure if this is a quirk with OOP in Python or if I am missing something else, hanks for the help!

2 Answers2

2

All the attributes you declared outside __init__ are class attributes (shared by all instances and the class itself), not instance attributes. If you want unique values for each instance, they must be initialized inside __init__, by attaching them to self (the instance being initialized), e.g.:

class bar:

    def __init__(self, name):
        self.myName = name
        self.mydict1 = {'a': '', 'b': ''}
        self.mydict2 = {}

    def addItem(self, x, y):
        self.mydict2[x] = y

Side-note: Read up on PEP8, the Python style guide. Your naming conventions are distinctly out of the ordinary, making your code harder to read (in particular, aside from built-ins like int, basically everyone uses CapWords for class names, and lowercase or lowercase_with_underscores for almost everything else).

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
0

Since mydict2 is assigned in the class rather than in the __init__ method, it is a property of the class, not of an object. To get the behaviour you expect, assign a self.mydict2 property in the __init__ method.

If you are used to a language like Java, this could be surprising. The behaviour in Java is that when you declare a field in the class, it belongs to an instance unless it is explicitly declared static, and if the field has an initializer then the initializer is executed when the object is created.

In Python, all code in the body of a class is executed at the time the class is created. (This technically includes the method definitions, but note that executing a method definition just results in the method being declared, not called.) Since the code is executed only once, only one dictionary gets created, and the class holds a reference to it, though this reference can be accessed through any instance of that class.

kaya3
  • 47,440
  • 4
  • 68
  • 97