Проверка ссылочного равенства в Python

Скажем, у меня есть класс в Python, в котором определен метод eq для сравнения атрибутов на равенство:

class Foo(object):
    # init code...

    def __eq__(self, other):
        # usual eq code here....

Как я могу затем сравнить два экземпляра Foo для эталонного равенства (то есть проверить, являются ли они одним и тем же экземпляром)? Если я сделаю:

f1 = Foo()
f2 = Foo()
print f1 == f2

Я получаю True, хотя это разные объекты.


person Adam Parkin    schedule 01.09.2011    source источник
comment
Неважно, разобрался, оператор is: f1 = Foo () f2 = Foo () print f1 is f2 возвращает false. Ссылка: tutorialspoint.com/python/python_basic_operators.htm   -  person Adam Parkin    schedule 01.09.2011
comment
Хорошая работа, найти ответ самому. Даже если вы сами решили проблему, все же нецелесообразно размещать решение как обычный ответ, а не комментарий к вопросу.   -  person SingleNegationElimination    schedule 01.09.2011
comment
is правильно, но вы также можете использовать id(f1) == id(f2).   -  person agf    schedule 01.09.2011
comment
Что я пытался сделать, но пока у меня нет репутации для этого.   -  person Adam Parkin    schedule 01.09.2011
comment
@agf: хорошая идея, но это подозрительно похоже на ответ на вопрос. Рассмотрите возможность добавления его как такового.   -  person SingleNegationElimination    schedule 01.09.2011
comment
@Adam Parkin: Вы должны иметь возможность ответить на свой вопрос независимо от репутации, хотя увидите всплывающее окно с советом, что вы должны давать ответ только в том случае, если это действительно ответ на вопрос.   -  person SingleNegationElimination    schedule 01.09.2011
comment
@Token Я не люблю публиковать ответы, показывающие, как что-то делать неправильно :)   -  person agf    schedule 01.09.2011
comment
возможный дубликат Как мне проверить, ссылаются ли две переменные на один и тот же объект в Python?   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 17.04.2015


Ответы (3)


Это оператор is

print f1 is f2
person SingleNegationElimination    schedule 01.09.2011
comment
Да, я понял это почти сразу после публикации. :) Приму этот ответ через несколько минут. Спасибо. - person Adam Parkin; 01.09.2011
comment
только что запустил это в терминале, объяснение? ››› c = 5 ››› d = 5 ››› c == d True ››› c is d True ››› id (c) 4298161480 ››› id (d) 4298161480 ››› - person Ryhan; 18.08.2017
comment
@Ryan см. stackoverflow.com/questions/21880308/ - person SingleNegationElimination; 18.08.2017

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

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

person Eli Collins    schedule 01.09.2011

Используйте ключевое слово is.

print f1 is f2

Некоторые интересные вещи (которые, я полагаю, зависят от реализации, но они верны в CPython) с ключевым словом is, заключаются в том, что None, True и False являются экземплярами singleton. Итак, True is True вернет True.

Строки также интернированы в CPython, поэтому 'hello world' is 'hello world' вернет True (вы не должны полагаться на это в обычном коде).

person Jonathan Sternberg    schedule 01.09.2011
comment
Просто отметим еще один недостаток реализации CPython: id целых значений не всегда одинаковы ... x=123123; ...some code...; x is 123123 иногда дает сбой. Это связано с тем, что объекты типа int выделяются динамически, поэтому иногда создаются дубликаты. Насколько мне известно, таким образом динамически создаются только целые числа и строки, так что это единственный раз, когда нужно беспокоиться о is подобном поведении. - person Eli Collins; 01.09.2011