Как Python устанавливает равенство между объектами? - PullRequest
4 голосов
/ 25 января 2012

Я отследил ошибку в моей программе до строки, где я проверял наличие объекта в списке объектов. Строка всегда возвращала False, что означало, что объекта нет в списке. На самом деле, это продолжалось, даже когда я делал следующее:

class myObject(object):
    __slots__=('mySlot')
    def __init__(self,myArgument):
        self.mySlot=myArgument
print(myObject(0)==myObject(0))        # prints False
a=0
print(myObject(a)==myObject(a))        # prints False
a=myObject(a)
print(a==a)                            # prints True

Раньше я использовал глубокую копию, но у меня недостаточно опыта работы с Python, чтобы знать, когда это необходимо и не нужно, или механически, в чем разница. Я также слышал о мариновании, но никогда не использовал его. Может кто-нибудь объяснить мне, что здесь происходит?

О, и еще одна вещь. Линия

if x in myIterable:

вероятно проверяет равенство между x и каждым элементом в myIterable, верно? Так что, если я могу изменить воспринимаемое равенство между двумя объектами, я могу изменить вывод этой строки? Есть ли встроенный для этого и всех других встроенных операторов?

Ответы [ 3 ]

6 голосов
/ 25 января 2012
  1. Передает второй операнд методу __eq__() первого.

  2. Неправильно.Он передает первый операнд методу __contains__() второго или выполняет итерацию второго, выполняющего сравнения на равенство, если такого метода не существует.

Возможно, вы хотелииспользуйте is, который сравнивает идентичность вместо равенства.

1 голос
/ 25 января 2012

myObject(a) == myObject(a) возвращает false, поскольку вы создаете два отдельных экземпляра myObject (с одним и тем же атрибутом a). Таким образом, два объекта имеют одинаковые атрибуты, но это разные экземпляры вашего класса, поэтому они не равны.

Если вы хотите проверить, есть ли объект в списке, тогда да,

if x in myIterable

вероятно, самый простой способ сделать это.

Если вы хотите проверить, имеет ли объект те же атрибуты, что и другой объект в списке, возможно, попробуйте что-то вроде этого:

x = myObject(a)
for y in myIterable:
    if x.mySlot == y.mySlot:
        print("Exists")
        break

Или вы можете использовать __eq__(self,other) в определении класса, чтобы установить условия для равенства.

1 голос
/ 25 января 2012

Строка myObject(0)==myObject(0) в вашем коде создает два разных экземпляра myObject, и, поскольку вы не определили __eq__, они сравниваются на предмет идентичности (т. Е. Расположения в памяти).

x.__eq__(y) <==> x==y и ваша строка около if x in myIterable:, использующая «сравнение равных» для ключевого слова in, верна, если только итерация не определяет __contains__.

print(myObject(0)==myObject(0))        # prints False

#because id(left_hand_side_myObject) != id(right_hand_side_myObject)

a=0
print(myObject(a)==myObject(a))        # prints False

#again because id(left_hand_side_myObject) != id(right_hand_side_myObject)

a=myObject(a)
print(a==a)                            # prints True

#because id(a) == id(a)
...