Поведение в этом примере выглядит следующим образом
In [1]: a = 1
In [2]: b = 2
In [3]: a = b
In [4]: b+=1
In [5]: b
Out[5]: 3
In [6]: a
Out[6]: 2
В этом примере, когда вы делаете a=b
, и a, и b указывают на одну и ту же ссылку, но когда вы b += 1
,операция добавления 1 к b, создает новое целочисленное значение 3
для b и b указывает на это значение, но a все еще указывает на старое значение 2
Обратите внимание, что при попытке сделать это с изменяемымтипы, подобные списку, работают так, как то, что вы исключали, могло бы произойти с целым числом
In [1]: a = [1]
In [2]: b = [2]
In [3]: a = b
In [4]: b.append(2)
In [5]: a
Out[5]: [2, 2]
In [6]: b
Out[6]: [2, 2]
In [7]: b += [3, 4];
In [8]: b
Out[8]: [2, 2, 3, 4]
In [9]: a
Out[9]: [2, 2, 3, 4]
Что теперь здесь произошло?Мы изменили b
, но a
также изменилось, это потому, что append
или обновление списка происходит in-place
, и поскольку a
указывает на b
, оба заканчивают тем, что обновляются!
То, что происходит для оператора +=
, определяется методом __iadd__
класса.Для int
-s все методы __iXXX__
возвращают новый экземпляр типа int.Для list
-s __iadd__(self, other)
делает self.extend(other); return self
, поэтому переменная продолжает указывать на один и тот же объект.
В результате даже целые числа могут вести себя как список, например здесь вежливость @ imposeren