user10375224
user10375224

Reputation: 13

Multiple Instance of Object Overwrites Python dict

I have a simple Dog class that I am trying to store information about in a dictionary. With multiple instances of the class, Im seeing that the values of the dictionary get overwritten with subsequent instances. Any idea why this is happening? Ive also included another variable that doesnt seem to change. I assume this is some attribute that has to do with Python Dictionaries. Any idea how to fix? Working on Python 3.6. Thanks in advance.

class DOG(object):
    info = {
        "name"    : '',
        "age"     : [],
        "breed"   : []
    }

    def __init__(self, name = '', age = 0, breed = '', goodDog = 0):
        self.info["name"]   = name
        self.info["age"]    = age
        self.info["breed"]  = breed
        self.goodDog        = bool(goodDog)



a = DOG(
    name = 'Sparky',
    age = 2,
    breed = 'collie',
    goodDog = False
)

print(a.info, a.goodDog) 

b = DOG(
    name = 'Lucky',
    age = 1,
    breed = 'labrador',
    goodDog = True
)

print(b.info, b.goodDog)
print(a.info, a.goodDog)

The output is:

{'name': 'Sparky', 'age': 2, 'breed': 'collie'} False
{'name': 'Lucky', 'age': 1, 'breed': 'labrador'} True
{'name': 'Lucky', 'age': 1, 'breed': 'labrador'} False

Upvotes: 1

Views: 276

Answers (2)

Carcigenicate
Carcigenicate

Reputation: 45745

You currently have info as a class attribute, which means it's shared by every instance. To have it as a instance attribute, you need to define it within __init__ (or some other method, but ideally the initializer):

def __init__(self, name = '', age = 0, breed = '', goodDog = 0):
    self.info = {"name" : name, 
                 "age" : age, 
                 "breed" : breed}
    self.goodDog = bool(goodDog) 

It would likely make more sense to have those all as separate instance variables though. I don't think you gain much by grouping them in a dictionary.

Upvotes: 0

Thierry Lathuille
Thierry Lathuille

Reputation: 24232

You have created a class attribute info, which you update during each instance creation (you don't create a new one).

As this class attribute isn't used at all, and since you want each instance to have its own, separate info, just create it in __init__:

class Dog:
    def __init__(self, name='', age=0, breed='', goodDog=False):
        self.info = {"name": name, "age": age,"breed": breed}
        self.goodDog = goodDog
​
​
a = Dog(
    name='Sparky',
    age=2,
    breed='collie',
    goodDog=False
)
​
print(a.info, a.goodDog) 
​
b = Dog(
    name='Lucky',
    age=1,
    breed='labrador',
    goodDog=True
)
​
print(b.info, b.goodDog)
print(a.info, a.goodDog)
# {'name': 'Sparky', 'age': 2, 'breed': 'collie'} False
# {'name': 'Lucky', 'age': 1, 'breed': 'labrador'} True
# {'name': 'Sparky', 'age': 2, 'breed': 'collie'} False

As a side note, I changed the class name to Dog and removed the spaces around '=' in parameters, to be more respectful of the Python PEP8 style guide

Upvotes: 1

Related Questions