#python #class
#python #класс
Вопрос:
from collections import deque
class testClass:
def __init__(self):
self.a = deque()
self.c = deque()
self.a.append(1)
self.c.append(2)
def testFunc1(self):
self.b = self.a
self.a = self.c
self.c = self.b
print(self.b.pop())
def testFunc2(self):
self.b = self.a
self.a = self.a.append(10)
print(self.b.pop())
TestInstance = testClass()
TestInstance.testFunc1() #answer will be 1
TestInstance.testFunc2() #answer will be 10
Я просто не понимаю, почему два ответа разные. Обе функции сначала присваиваются self.a
self.b
. Из результатов мы можем видеть, что если мы посмотрим на testFunc2
, self.b
изменится, если self.a
изменится. Однако, если мы посмотрим на testFunc1
, self.b
не изменится, если self.a
изменится. Почему это произошло? Кто-нибудь может мне объяснить?
Комментарии:
1.
self.b
изменилось бы, если бы значение deque, на которое первоначально указывалself.a
(на которое теперь ссылаетсяself.c
), изменилось. Вероятно, вам следует прочитать nedbatchelder.com/text/names.html чтобы понять, что на самом деле означают все эти назначения.2. спасибо за ваш ответ. я только что нашел другой веб-сайт, который мог бы визуализировать коды python. Я нахожу чрезвычайно полезным разобраться в вопросах такого типа, как мой.
3. забыл добавить ссылку. Веб-сайт, упомянутый выше, является pythontutor.com/visualize.html
Ответ №1:
Ключ в том, чтобы знать, на что deque
ссылается каждый атрибут после каждого присвоения.
После __init__
выполнения у вас есть два значения deque; допустим, это self.a
относится к d1
и self.c
ссылается на d2
. Затем d1
содержит число 1 и d2
содержит число 2.
При testFunc1
вызове self.b
создается ссылка на d1
. Затем self.a
изменяется на ссылку на d2
, а затем self.c
создается ссылка на d1
. Последняя строка удаляет значение из d1
и печатает его, выводя 1.
При testFunc2
запуске self.a
по-прежнему ссылается на d2
и self.b
, и self.c
оба ссылаются на d1
. Первое присвоение делает self.b
ссылку на d2
. Следующее присваивание добавляет 10 к d2
, но затем делает self.a
ссылку на None
, поскольку это то, что deque.append
возвращает (не само обновленное deque
). self.b.pop()
немедленно удаляет 10, которые мы только что добавили к d2
, и это значение печатается.
Комментарии:
1. спасибо за ваше объяснение. Думаю, я понял, что вы сказали, но все же хочу уточнить у вас одну вещь. После первого присваивания в
testFunc2
обаself.a
иself.b
ссылаются наd2
.self.a.append(10)
добавит 10 кd2
, но вернетNone
. Следовательно, второе присвоениеself.a = self.a.append(10)
заставитself.a
указывать на другой объект (который являетсяNone
). В то же время,self.b
все еще указывает наd2
(который только что добавлен10
). Правильно ли я понимаю? Еще раз спасибо!2. Именно так.
3. Отлично! Спасибо!
Ответ №2:
Проблема в том self.b = self.a
. Используя оператор =, вы думаете, что это создает новый объект; на самом деле это не так. Это только создает новую переменную, которая разделяет ссылку на исходный объект. Когда вы изменяете self.a
, добавляя другой элемент, self.b
изменения также происходят, потому что они указывают на одно и то же. Используйте copy() или deepcopy() в зависимости от того, что вам нужно. Для этого примера, я думаю, copy() достаточно.
измените self.b = self.a
на self.b = copy.copy(self.a)
, вы получите то, что ожидаете. Пожалуйста, не забудьте import copy
.
Подробнее читайте copy в Python.