1

I am getting an wierd output when I try to append an object created in the loop

animals.txt

ralph, dog, 3
buster, cat, 8
sammy, bird, 5
mac, dog, 1
coco, cat, 6

pet.py

class Pet:
    # The __init__ method initializes the data attributes of the Profile class
    def __init__(self, name ='', animal_type = '', age = ''):
        self.__name = name
        self.__animal_type = animal_type
        self.age = 0

    def __str__(self):
        string = self.__name + ' ' + self.__animal_type + ' ' + str(self.age)
        return string

    def set_name(self, name):
        self.__name = name

    def get_name(self):
        return self.__name

    def set_animal_type(self, breed):
        self.__animal_type = breed

    def get_animal_type(self):
        return self.__animal_type

    def set_age(self, old):
        self.age = old    

    def get_age(self):
        return self.age  

animals.py

import pet

myPet = pet.Pet()

animals = []

infile = open("animals.txt", "r")

lines = infile.readlines()

for line in lines:
    data = line.split(",")
    myPet.set_name(data[0])
    myPet.set_animal_type(data[1])
    myPet.set_age(data[2])
    # print (data[0], data[1], data[2])
    print(myPet)
    animals.append(myPet)    

print(animals)

infile.close()

when I print the object created with each iteration with print(myPet) I get this;

ralph dog 3

buster cat 8

sammy bird 5

mac dog 1

coco cat 6

I then append the object myPet and this is the output repeated 5 times in the list when i print(animals)

pet.Pet object at 0x00000185DCAE1128

I am not sure what is going on I have tried

myPet.set_name(data[0])
animals.append(myPet.get_name)

and

myPet.set_name(data[0])
name = myPet.get_name
animals.append(name)

giving the same error

bound method Pet.get_name of pet.Pet object at 0x000002C0F0BF6C88

  • 2
    Create a new `Pet` for each row of data rather than creating one `Pet` and changing its properties for each row. – ggorlen Oct 20 '18 at 06:22
  • Also, don't use setters and getters in Python, see https://stackoverflow.com/questions/2627002/whats-the-pythonic-way-to-use-getters-and-setters – Thierry Lathuille Oct 20 '18 at 06:35
  • I have to use getters and setters due to it being a Uni task .. they want us to always use get and set, nothing i can do about it .. but have learnt that in Python it is not necessary :-) – Scot Henderson Oct 20 '18 at 07:02
  • Possible duplicate of [Creating a list of objects in Python](https://stackoverflow.com/questions/3182183/creating-a-list-of-objects-in-python) – jimmy Oct 20 '18 at 07:26

2 Answers2

2

Changing your code so that you create a new Pet instance for every Pet, rather than changing the values of an existing Pet instance will mean you are appending the different pet values to your list.

import pet

animals = []

infile = open("animals.txt", "r")

lines = infile.readlines()

for line in lines:
    data = line.split(",")
    myPet = pet.Pet()
    myPet.set_name(data[0])
    myPet.set_animal_type(data[1])
    myPet.set_age(data[2])
    # print (data[0], data[1], data[2])
    print(myPet)
    animals.append(myPet)    

print(animals)

infile.close()
Ashleigh
  • 86
  • 2
  • I am still getting --> pet.Pet object at 0x000002460D04D518 <-- with this code when i print(animals), its like it is calling a memory address instead of the actual object. – Scot Henderson Oct 20 '18 at 07:01
2

When you print a single instance of MyPet, Python calls MyPet's __str__ method to get a string representation.

When you print a list of objects, Python displays the result of calling repr on each element of the list. By default this will produce

a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object

You can override this behaviour by adding a __repr__ method to MyPet; this code makes __str__ and __repr__ the same:

class MyPet:

    def __repr__(self):
        string = self.__name + ' ' + self.__animal_type + ' ' + str(self.age)
        return string

    __str__ == __repr__

Conventionally, the output of __repr__ is

a string that would yield an object with the same value when passed to eval()

which you could do with this code:

class MyPet:

    def __repr__(self):
        return  "MyPet(name='{}', animal_type='{}', age={})".format(self.__name,
                                                                    self.__animal_type,
                                                                    self.age)

    def __str__(self):
        string = self.__name + ' ' + self.__animal_type + ' ' + str(self.age)
        return string
snakecharmerb
  • 47,570
  • 11
  • 100
  • 153