При добавлении объекта в список с помощью python создается адрес памяти объекта вместо данных внутри объекта. - PullRequest
0 голосов
/ 20 октября 2018

Я получаю странный вывод, когда пытаюсь добавить объект, созданный в цикле

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()

при печати объекта, созданного на каждой итерации, с помощью print (myPet) Я получаю это;

Ральф собака 3

Бастер кошка 8

Сэмми Птица 5

Mac Dog 1

Кокоcat 6

Затем я добавляю объект myPet, и этот вывод повторяется 5 раз в списке, когда i print (animals)

pet.Pet объект 0x00000185DCAE1128

Я не уверен, что происходит, я пытался

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

и

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

, выдавая ту же ошибку

связанный метод Pet.get_name of pet.Pet объекта в 0x000002C0F0BF6C88

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Когда вы print один экземпляр MyPet, Python вызывает MyPet метод __str__ для получения строкового представления.

Когда вы печатаете список объектов, Python отображаетрезультат вызова repr для каждого элемента списка.По умолчанию это выдает

строку, заключенную в угловые скобки, которая содержит название типа объекта вместе с дополнительной информацией, часто включая имя и адрес объекта

Вы можете переопределить это поведение, добавив метод __repr__ к MyPet;этот код делает __str__ и __repr__ одинаковыми:

class MyPet:

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

    __str__ == __repr__

Обычно, вывод __repr__ представляет собой

строку, которая даст объект с таким жезначение при передаче в eval ()

, которое вы можете сделать с этим кодом:

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
0 голосов
/ 20 октября 2018

Изменение вашего кода для создания нового экземпляра Pet для каждого Pet вместо изменения значений существующего экземпляра Pet будет означать, что вы добавляете различные значения Pet в свой список.

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()
...