Меняется значение атрибута класса Python

Почему меняется значение атрибута класса Cell.value?

class Cell:

    def __init__(self):
        self.value = None

    def show(self):
        print(self.value)
        
    def change_value(self,val):
        self.value = val

class Sudoku:
    
    def __init__(self):
        self.pos = [[Cell()]*9]*9
        self.flag = False

    def set_value(self, x, y, value):
        self.pos[x][y].change_value(value)
        print(self.pos[x][y].value)

    def get_value(self, x, y):
        return self.pos[x][y].value

a.set_value(8,1,2)
a.set_value(8,3,5)
a.set_value(8,8,6)
a.pos[8][1].show()
print(a.get_value(8,3))

2
5
6
6
6

Значение a.pos[8][1].value при вызове метода set_value принимает значение 5, но потом принимает значение 6. От куда взялась эта 6 и почему поменялось значение?


Ответы (1 шт):

Автор решения: DiHASTRO

Давайте прочитаем ваш код по порядку его выполнения (объявление классов и их методов опустим, пойдём по порядку):

a.set_value(8, 1, 2)

Видим обращение к class Sudoku, method: set_value, читаем: он меняет у некоторой "координаты" переменной pos (а именно pos[8][1]) переменную value. Рассмотрим то, как вы объявили переменную pos (self.pos у класса Sudoku):

[[Cell()]*9]*9 и вся проблема кроется именно в этой строке. Вы как бы не создаёте отдельно новую Cell() для каждого места в двумерном списке, а копируете 81 раз одну и ту же. В итоге выходит, что к какому бы месту вы не обращались в self.pos, вы всегда обращаетесь к одному и тому же объекту.

Реализовать можно по разному заполнение self.pos:

Можно взять банально написать

self.pos = [ [Cell(), Cell(), ..., Cell()], [Cell(), Cell(), ..., Cell()], ..., [Cell(), Cell(), ..., Cell()]], но мы ведь с вами хотим покрасивее, полагаю?

Например:

...
self.pos = []
for i in range(9):
    part_of_pos = []
    for j in range(9):
        part_of_pos.append(Cell())
    self.pos.append(part_of_pos)
...

Впрочем, вы ошибку, полагаю, поняли, дальше уже только ваша фантазия!


Всем добра

→ Ссылка