Разные экземпляры класса по ошибке имеют общую переменную, как исправить?

Рейтинг: 0Ответов: 1Опубликовано: 08.03.2023

У меня есть класс Unit

class Unit:
    unit_id = int()
    genome = list()
    brain = [[tuple()]] * 4

    x = int()
    y = int()
    color = ""
    health = 100
    hunger = 0
    pocket_seeds = 0
    kill = False

    def __init__(self, x, y, from_genome=None):
        ids = [unit.unit_id for unit in units]
        while True:
            self.unit_id = randrange(0, 100000)
            if self.unit_id not in ids:
                break
        if from_genome is None:
            for gen in range(15):
                self.genome.append("".join(choice(DIGITS) for i in range(6)))
        else:
            for gen in from_genome:
                result_gen = ""
                for h in gen:
                    if randrange(100) <= 10:
                        result_gen += choice(DIGITS)
                    else:
                        result_gen += h
                self.genome.append(result_gen)
        r = 0
        g = 0
        b = 0
        for gen in self.genome:
            order = 0
            if int(gen[0], 20) < 10:
                neuron1 = INPUTS[int(gen[1], 20)]
            else:
                neuron1 = HIDDEN[round(int(gen[1], 20) / 4.75)]  # 19 / 4 = 4.75
                order += 1
            if int(gen[2], 20) < 10:
                neuron2 = HIDDEN[round(int(gen[3], 20) / 4.75)]
                order += 1
            else:
                neuron2 = OUTPUT[round(int(gen[3], 20) / 3.166666)]  # 19 / 6 = 3.166666......
                order += 3
            weight = int(gen[-2:], 20) * 0.01
            self.brain[order - 1].append((neuron1, neuron2, weight))
            r += int(int(gen[:2], 20) / 1.5647058823529)
            g += int(int(gen[2:4], 20) / 1.5647058823529)
            b += int(int(gen[-2:], 20) / 1.5647058823529)
        self.x = x
        self.y = y
        self.color = '#%02x%02x%02x' % (int(r / len(self.genome)), int(g / len(self.genome)), int(b / len(self.genome)))
        elem = canvas.create_oval(self.x * 10, self.y * 10, self.x * 10 - 10, self.y * 10 - 10, fill=self.color)
        append(matrix[x][y], ("u", self.unit_id, elem))
        units.append(self)

Я создаю 300 экземпляров этого класса в цикле for

for u in range(300):
    newbie = Unit(randrange(0, 100), randrange(0, 100))
    print(id(newbie))  # id экземпляров разные
    print(id(newbie.genome))  # но id их важной переменной один, как так?
print("Units generated")

Но по какой-то неведомой мне причине, каждый экземпляр редактирует один и тот же участок памяти, из-за чего всё идёт на перекосяк. То есть у каждого класса len(self.genome) должен равняться 15, но в итоге он просто прибавляет к общему genome лишние элементы, то есть len(self.genome) == 4500. Как мне сделать чтобы каждый экземпляр моего класса был полностью самостоятельным?

Ответы

▲ 4Принят

Это происходит, потому что переменная genome классовая, а не объектная. Чтобы это исправить нужно перенести ее инициализация внутрь метода __init__ и сделать объектной.

def __init__(self):
    self.genome = []
    # дальше ваш остальной код

Так же нужно сделать с остальными переменными, которые вы хотите, чтобы были привязаны не ко всему классу, а к конкретному объекту класса.