Ссылка на Назначение в изменяемых объектах Python

Назначение:

>>> a = ['spam'] >>> b = ['spam'] >>> a is b False 

Справка:

 >>> c = ['spam'] >>> d = c >>> c is d True 
  1. В чем разница между ними выше?
  2. Почему результаты назначения False ?
  3. Почему ссылочные результаты « True ?

Ваш первый фрагмент создает два уникальных объекта списка, которые не совпадают. Следовательно, a is b возвращает false, потому что a и b указывают на разные объекты:

           + ------ +
 a ------> |  список |
           + ------ +

           + ------ +
 b ------> |  список |
           + ------ +

Ваш второй фрагмент создает единый объект списка и указывает на c и d на эти объекты, поэтому c is d возвращает true:

           + ------ +
 c ------> |  список |  <------ d
           + ------ +

Обратите внимание на следующее: http://docs.python.org/3/reference/datamodel.html :

Каждый объект имеет идентификатор, тип и значение. Идентификация объекта никогда не изменяется после его создания; вы можете думать об этом как о адресе объекта в памяти. Оператор is сравнивает идентичность двух объектов; функция id() возвращает целое число, представляющее его идентификатор.

Итак is и == очень разные; в то время как первый сравнивает идентичность объекта, последний сравнивает значения объектов. Действительно, == тесты в ваших фрагментах вернут true.


Учитывая приведенное выше объяснение, может показаться сюрпризом, что история немного отличается от строк:

 >>> a = 'str' >>> b = 'str' >>> >>> a is b True 

Это происходит из-за интернирования строк , который встречается в CPython (т. Е. Специфичен для реализации). Поэтому, если один и тот же строковый литерал отображается в двух разных местах, тот же строковый объект будет использоваться для обоих (с ограничениями).

Это более подробно объясняется в разделе «Интерпретация строки Python» .

при сравнении с is , как и a is b , это то же самое, что id(a) == id(b) , код xx=['spam'] каждый раз создает новый список и назначает его xx , его id изменяется каждый время, так что a is b дает значение False

Это не имеет никакого отношения к какому-то (неутомимому) вопросу «задание против ссылки».

 >>> a = ['spam'] 

создает список со строкой «spam» в нем и связывает его с именами «a» в текущей области.

 >>> b = ['spam'] 

создает другой список со строкой «spam» в нем и связывает его с именами «b» в текущей области.

Вы создаете два списка, у вас есть два списка. Простое.

 >>> c = ['spam'] 

создает еще один список со строкой «spam» в нем и связывает его с именами «c» в текущей области.

 >>> d = c 

связывает имя 'd' с тем, что 'c' привязано к тому времени в текущей области.

Здесь вы создаете один список и связываете с ним 2 имени. Оба названия указывают на один и тот же объект.

Дело в том, что «переменные» Python не называются именами памяти, просто именами, указывающими на объекты. В данный момент один объект может быть привязан к (указанному) любым числом имен (и даже вообще не именем).

Позвольте мне просто добавить несколько вызовов функций к тому, что вы изначально делали. Думаю, ты его поднимешь.

 >>> a = ['spam'] >>> b = ['spam'] >>> a is b False >>> id(a) 4552359808 >>> id(b) 4552446176 >>> a == b True >>> c = ['spam'] >>> d = c >>> id(c) 4552513296 >>> id(d) 4552513296 >>> c is d True >>> c == d True >>> print id.__doc__ id(object) -> integer Return the identity of an object. This is guaranteed to be unique among simultaneously existing objects. (Hint: it's the object's memory address.)