Как `is` работает в случае эфемерных объектов, использующих один и тот же адрес памяти?

Обратите внимание, что этот вопрос может быть (является ли?) специфичным для CPython.

Скажем, у вас есть какой-то список, и проверьте копии списка на идентичность друг с другом:

>>> a=list(range(10))
>>> b,c=a[:],a[:]
>>> b is c
False
>>> id(b), id(c)
(3157888272304, 3157888272256)

Там нет сильных толчков. Но если мы сделаем это более эфемерным способом, поначалу все может показаться немного странным:

>>> a[:] is a[:]
False  # <- two ephemeral copies not the same object (duh)
>>> id(a[:]),id(a[:])
(3157888272544, 3157888272544)   # <- but two other ephemerals share the same id..? hmm....

...пока мы не поймем, что, вероятно, здесь происходит. Я не подтвердил это, посмотрев на реализацию CPython (я едва умею читать C++, так что, если честно, это было бы пустой тратой времени), но, по крайней мере, кажется очевидным, что даже если два объекта имеют одинаковый идентификатор, CPython умен. достаточно знать, что это не один и тот же объект.

Предполагая, что это правильно, мой вопрос: какие критерии использует CPython, чтобы определить, являются ли два эфемерных объекта разными объектами, учитывая, что они имеют один и тот же идентификатор (предположительно, из соображений эффективности - см. ниже)? Возможно, он смотрит на время, когда он был отмечен как сборщик мусора? Время создания? Или что-то другое...?

Моя теория о том, почему у них один и тот же идентификатор, заключается в том, что, вероятно, CPython знает, что эфемерная копия списка уже была создана и ожидает сборки мусора, и он просто эффективно повторно использует ту же память. место нахождения. Было бы здорово, если бы ответ мог прояснить/подтвердить и это.


person Rick supports Monica    schedule 23.01.2019    source источник
comment
Вы НЕ МОЖЕТЕ когда-либо сравнивать два различных эфемерных объекта, которые имеют один и тот же идентификатор — тот факт, что вы их сравниваете, подразумевает, что оба они существуют в один и тот же момент времени, а это означает, что нет возможности для второго объекта быть выделенным в тот же самый момент времени. тот же адрес, что и первый.   -  person jasonharper    schedule 23.01.2019
comment
Объекты list, которые вы создаете для передачи в id, перестают существовать после того, как вы передаете их в id. Помните, что подсчет ссылок CPython восстанавливает объект, как только счетчик ссылок становится равным нулю. Среда выполнения CPython имеет частно управляемую кучу, которая очень хорошо подходит для повторного использования памяти. Python пошел дальше и повторно использовал ту же память для выделения вашего нового объекта списка, переданного второму вызову id. Другими словами, эти два объекта не имеют перекрывающихся жизненных циклов, поэтому id не гарантированно уникальны.   -  person juanpa.arrivillaga    schedule 23.01.2019
comment
@jasonharper Отлично. Но мой вопрос: как CPython успешно определяет, что это не один и тот же объект?   -  person Rick supports Monica    schedule 23.01.2019
comment
@RickTeachey, вы никогда не сравниваете их на предмет идентичности объекта ... где CPython успешно определяет, что это не один и тот же объект?   -  person juanpa.arrivillaga    schedule 23.01.2019
comment
@juanpa.arrivillaga Понятно. Но мой вопрос: как CPython получает здесь False? Он должен проверять ЧТО-ТО кроме идентификатора   -  person Rick supports Monica    schedule 23.01.2019
comment
@juanpa.arrivillaga эта строка: >>> a[:] is a[:]   -  person Rick supports Monica    schedule 23.01.2019
comment
@RickTeachey, это не. Он проверяет идентификатор. Но если вы используете оператор is, они не будут иметь одинаковый идентификатор во время проверки   -  person juanpa.arrivillaga    schedule 23.01.2019
comment
В a[:] is a[:] две стороны НЕ имеют одинаковый идентификатор.   -  person jasonharper    schedule 23.01.2019
comment
@jasonharper Да, это ответ; конечно, сторона A и сторона B находятся в памяти одновременно и позже GCed. Ага, имеет смысл!   -  person Rick supports Monica    schedule 23.01.2019
comment
Этот вопрос не является дубликатом, потому что я задаю нечто иное, чем предложенный вопрос о дублировании.   -  person Rick supports Monica    schedule 23.01.2019
comment
@RickTeachey, о чем вы спрашиваете, и как на это не отвечает дубликат?   -  person juanpa.arrivillaga    schedule 23.01.2019
comment
@juanpa.arrivillaga Я не осознавал, что два объекта существуют одновременно во время операции is. Это другой вопрос, потому что другой спрашивал, почему идентификаторы одинаковы; Я спрашивал, почему операция is завершается успешно.   -  person Rick supports Monica    schedule 23.01.2019
comment
Я по-прежнему утверждаю, что это действительный дубликат, потому что ваше фундаментальное непонимание того, что объекты имели один и тот же идентификатор в течение своей жизни. но не стесняйтесь голосовать за повторное открытие.   -  person juanpa.arrivillaga    schedule 23.01.2019
comment
То, что что-то является дубликатом, не означает, что это плохой вопрос. Время от времени он появляется в различных формах. Я добавил несколько других, более тесно связанных повторяющихся целей.   -  person juanpa.arrivillaga    schedule 23.01.2019


Ответы (1)


Два неизменяемых объекта, имеющих один и тот же адрес, с вашей точки зрения, будут неотличимы друг от друга.

Дело в том, что когда вы выполняете a[:] is a[:], оба объекта находятся не по одному и тому же адресу - для того, чтобы оператор идентификации is мог сравнить оба объекта, оба операнда должны существовать - так что ссылка на объект слева, когда на самом деле запускается собственный код для is.

С другой стороны, когда вы выполняете id(a[:]),id(a[:]), объект в круглых скобках при первом вызове остается без каких-либо ссылок, как только вызов функции id выполняется, и уничтожается, освобождая блок памяти для использования вторым a[:].

person jsbueno    schedule 23.01.2019