2014-02-13 6 views
6

Я очень путать с кодом питона ниже:Почему id (A()) == id (A()) отличается от A() есть A()?

>>> class A(): pass 
... 
>>> id(A()) == id(A()) 
True 
>>> id(A()) 
19873304 
>>> id(A()) 
19873304 
>>> A() is A() 
False 
>>> a = A() 
>>> b = A() 
>>> id (a) == id (b) 
False 
>>> a is b 
False 
>>> id (a) 
19873304 
>>> id (b) 
20333272 
>>> def f(): 
...  print id(A()) 
...  print id(A()) 
... 
>>> f() 
20333312 
20333312 

я могу сказать себе ясно, что питон делать при создании объектов.
Может ли кто-нибудь рассказать мне больше о том, что произошло? Благодаря!

+0

См. Http://stackoverflow.com/questions/2906177/what-is-the-difference-between-a-is-b-and-ida-idb-in-python –

ответ

3

Когда вы говорите

print id(A()) == id(A()) 

вы создаете объект типа A и передавая ее id функции. Когда функция возвращается, нет ссылок на этот объект, созданный для параметра. Таким образом, счетчик ссылок становится равным нулю, и он становится готовым к сбору мусора.

Когда вы делаете id(A()) в том же выражении снова, вы пытаетесь создать другой объект того же типа. Теперь Python может попытаться повторно использовать ту же ячейку памяти, которая использовалась для предыдущего созданного объекта (если он уже собран мусором). В противном случае он создаст его в другом месте. Таким образом, id может быть или не быть одинаковым.

Если вы,

print A() is A() 

Мы создаем объект типа A и мы пытаемся сравнить его с другим объектом типа A. Теперь в этом выражении все еще упоминается первый объект. Таким образом, он не будет помечен для сбора мусора, и поэтому ссылки будут разными.

Предложение: Никогда не делайте ничего подобного в производственном кодексе.

Цитируя docs,

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

5

Два разных объекта могут находиться в одном и том же месте в памяти, , если один из них освобожден до создания другого.

То есть, если вы выделили объект, возьмите его идентификатор, а затем больше не ссылайтесь на него, он может быть освобожден, поэтому другой объект может получить один и тот же идентификатор.

В отличие от этого, если вы сохраните ссылку на первый объект, любой последующий выделенный объект обязательно будет иметь другой идентификатор.

0

A() создает временную переменную, а затем очищает его

поэтому следующий A() получает тот же идентификатор (который был только сбор мусора, хотя это поведение, вероятно, не гарантировано)) ... Таким образом, когда вы распечатывали они имеют один и тот же идентификатор

id(A()) == id(A()) 

должен создать две временные переменные друг с другом ид

0

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

Смежные вопросы