Подтвердить что ты не робот

`id` в Python 2.7,` is`, идентификация объекта и определяемые пользователем методы

Результаты из кода, приведенного ниже в Python 2.7, показались мне противоречием. Оператор is должен работать с идентификатором объекта и, следовательно, id. Но их результаты расходятся, когда я смотрю на пользовательский метод. Почему это?

py-mach >>class Hello(object):
...  def hello():
...    pass
...
py-mach >>Hello.hello is Hello.hello
False
py-mach >>id(Hello.hello) - id(Hello.hello)
0

Я нашел следующий отрывок из описания

4b9b3361

Ответ 1

Документация Python для функции id гласит:

Верните "идентификатор" объекта. Это целое число (или длинное целое число), которое гарантировано будет уникальным и постоянным для этого объекта в течение его жизни. Два объекта с неперекрывающимся временем жизни могут иметь одинаковое значение id().

(акцент мой)

Когда вы выполняете id(Hello.hello) == id(Hello.hello), объект метода создается только кратко и считается "мертвым" после первого вызова "id". Из-за вызова id вам нужно всего лишь Hello.hello быть живым в течение короткого периода времени - достаточно, чтобы получить идентификатор. Когда вы получите этот id, объект будет мертв, а второй Hello.hello может повторно использовать этот адрес, что делает его похожим на то, что оба объекта имеют одинаковый идентификатор.

Это не похоже на выполнение Hello.hello is Hello.hello - оба экземпляра должны жить достаточно долго, чтобы их можно было сравнивать друг с другом, поэтому у вас есть два живых экземпляра.

Если вы попробовали:

>>> a = Hello.hello
>>> b = Hello.hello
>>> id(a) == id(b)
False

... вы получите ожидаемое значение False.

Ответ 2

Это "простое" следствие работы распределителя памяти. Это очень похоже на случай:

>>> id([]) == id([])
True

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

Никогда не полагайтесь на это поведение, поскольку оно разрешено ссылкой на язык, но, конечно, не требуется.