Система атрибутов унаследованного класса Python

#python-3.x #inheritance

#python-3.x #наследование

Вопрос:

 class Board:

    array = [[" ", " ", " "],
             [" ", " ", " "],
             [" ", " ", " "]]

    def reset(self):
        self.array = [[" ", " ", " "],
                      [" ", " ", " "],
                      [" ", " ", " "]]


class AI(Board):

    def __init__(self):
        self.array[0][0] = "X"


ai = AI()
board = Board() 
print(ai.array)  # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
print(board.array)  # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
ai.reset()
print(ai.array)  # [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
print(board.array)  # [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
  

Мой вопрос в том, почему board.array изменен, в то время как ai.array был. Если они связаны друг с другом, почему оба атрибута не изменяются вместе, пока выполняется метод, принадлежащий AI.

Ответ №1:

Это можно понять следующим образом:

  • Когда вы получаете self.array возможность использовать или изменять его, как в выражении self.array[0][0] = "X" , тогда

    • сначала проверяется экземпляр, чтобы увидеть, имеет ли он такой атрибут;
    • если этого не происходит, тип экземпляра проверяется на наличие атрибута.

(это упрощение того, что происходит, но это все, что вам нужно знать для этого случая)

  • Когда вы устанавливаете экземпляр, как вы делаете в выражении self.array = [...] , вы устанавливаете атрибут непосредственно в экземпляре

Итак, в вашем примере кода:

 print(ai.array)     # ai does not have an array, Board.array is returned
print(board.array)  # board does not have an array, Board.array is returned
ai.reset()          # this adds an attribute to ai
print(ai.array)     # ai **does** have an array, it is returned
print(board.array)  # board does not have an array, Board.array is returned