Почему происходит изменение узла, который я создаю и добавляю в массив?

Я создаю узел с пустым массивом, затем создаю еще один узел и добавляю его в этот массив, используя классы. Однако, почему второй узел, который должен иметь пустой массив, вместо этого содержит ссылку на самого себя? <br/> <pre><code class="python">class Node:
	def __init__(self, p_type, p_text, p_mas_connections = []):
		self.type = p_type
		self.text = p_text
		self.mas_connections = p_mas_connections

	def print_connections(self):
		print(self.type)
		print(self.text)
		print(self.mas_connections)

	def change_connections(self, p_position, p_node): 
		self.mas_connections[p_position] = p_node

	def append_connections(self, p_node):
		print(f'self.mas_connections {self.mas_connections}')
		self.mas_connections.append(p_node)
		print(f'self.mas_connections {self.mas_connections}')

	def return_selected_node_from_mas_connections(self, p_position):
		return self.mas_connections[p_position]

root = Node('key_word', 'program', [Node("identifier", None)])

current = root.return_selected_node_from_mas_connections(0)
current.print_connections()

s = Node('tochka_s_zapyatoy', ';')
s.print_connections()

current.append_connections(s)
s.print_connections()</code></pre> <br/> <br/> Вывод <br/> identifier <br/> None <br/> [] <br/> tochka_s_zapyatoy <br/> ; <br/> [] <br/> identifier <br/> None <br/> [<__main__.Node object at 0x000001AEDE08C3E0>] <br/> tochka_s_zapyatoy <br/> ; <br/> [<__main__.Node object at 0x000001AEDE08C3E0>] # Здесь должен быть просто [] <br/> <br/> Где именно я ошибся в своем понимании?
  • 26 сентября 2024 г. 18:53
Ответы на вопрос 2
Ваша проблема заключается в том, как вы используете параметр по умолчанию для `p_mas_connections` в конструкторе класса `Node`. Когда вы задаете значение по умолчанию (`[]`) для параметра, оно создается один раз, и все экземпляры класса `Node`, которые используют это значение по умолчанию, будут ссылаться на один и тот же объект (список). Поэтому, когда вы добавляете новый элемент в массив подключений одного узла, этот элемент также появляется в массиве у всех других узлов, которые используют тот же массив по умолчанию.

Чтобы исправить эту проблему, вы можете использовать `None` в качестве значения по умолчанию и инициализировать массив внутри конструктора, если он не был передан:

```python
class Node:
    def __init__(self, p_type, p_text, p_mas_connections=None):
        if p_mas_connections is None:
            p_mas_connections = []
        self.type = p_type
        self.text = p_text
        self.mas_connections = p_mas_connections

    def print_connections(self):
        print(self.type)
        print(self.text)
        print(self.mas_connections)

    def change_connections(self, p_position, p_node): 
        self.mas_connections[p_position] = p_node

    def append_connections(self, p_node):
        print(f'self.mas_connections {self.mas_connections}')
        self.mas_connections.append(p_node)
        print(f'self.mas_connections {self.mas_connections}')

    def return_selected_node_from_mas_connections(self, p_position):
        return self.mas_connections[p_position]

root = Node('key_word', 'program', [Node("identifier", None)])

current = root.return_selected_node_from_mas_connections(0)
current.print_connections()

s = Node('tochka_s_zapyatoy', ';')
s.print_connections()

current.append_connections(s)
s.print_connections()
```

Теперь, если вы создаете новый узел без явного указания значения для `p_mas_connections`, он будет инициализирован пустым списком, и это предотвратит проблемы с разделением ссылок на один и тот же список. После внесения изменений код будет вести себя так, как вы ожидаете, и массив подключений второго узла будет оставаться пустым, если по умолчанию его не передадут.
Стандартная ошибка новичка в 
def __init__(self, p_type, p_text, p_mas_connections = []):
правильно p_mas_connections=None, а далее в коде например так
self.mas_connections = [] if p_mas_connections is None else p_mas_connections

гуглить "python mutable default argument"
Похожие вопросы