Изменяемый объект должен иметь хотя бы метод, способный изменять объект. Например, у объекта list
есть метод append
, который фактически будет мутировать объект:
>>> a = [1,2,3]
>>> a.append('hello') # `a` has mutated but is still the same object
>>> a
[1, 2, 3, 'hello']
но класс float
не имеет метода для изменения объекта с плавающей точкой. Вы можете сделать:
>>> b = 5.0
>>> b = b + 0.1
>>> b
5.1
но операнд =
не является методом. Он просто устанавливает связь между переменной и тем, что находится справа от нее, и ничего больше. Он никогда не меняет и не создает объекты. Это объявление того, на что будет указывать переменная, начиная с этого момента.
Когда вы делаете b = b + 0.1
, операнд =
связывает переменную с новым числом с плавающей точкой, которое создается с результатом 5 + 0.1
.
Когда вы присваиваете переменную существующему объекту, изменяемому или нет, операнд =
связывает переменную с этим объектом. И больше ничего не происходит
В любом случае =
просто связывает. Он не меняет и не создает объекты.
Когда вы делаете a = 1.0
, операнд =
создает не число с плавающей точкой, а часть 1.0
строки. На самом деле, когда вы пишете 1.0
, это сокращение для float(1.0)
вызова конструктора, возвращающего объект с плавающей точкой. (По этой причине, если вы наберете 1.0
и нажмете Enter, вы получите «echo» 1.0
, напечатанное ниже; это возвращаемое значение функции конструктора, которую вы вызвали)
Теперь, если b
- это число с плавающей точкой, и вы присваиваете a = b
, обе переменные указывают на один и тот же объект, но на самом деле переменные не могут соединяться между собой, потому что объект неизменен, и если вы делаете b += 1
, теперь b
указывают на новый объект, а a
все еще указывает на старого и не может знать, на что b
указывает.
, но если c
, скажем, list
, и вы назначаете a = c
, то теперь a
и c
могут "общаться", потому что list
является изменяемым, и если вы делаете c.append('msg')
, тогда просто проверяя a
вы получите сообщение.
(Между прочим, у каждого объекта есть уникальный идентификатор, связанный с ним, который вы можете получить с помощью id(x)
. Таким образом, вы можете проверить, является ли объект тем же или нет, проверяя, изменился ли его уникальный идентификатор.)