В Python объект() равен чему угодно, кроме самого себя?
Если у меня есть код my_object = object()
в Python, будет ли my_object
равным чему-либо, кроме самого себя?
Я подозреваю, что ответ лежит в методе __eq__
объекта по умолчанию, возвращаемого object()
. Какова реализация __eq__
для этого объекта по умолчанию?
EDIT: я использую Python 2.7, но также интересуюсь ответами Python 3. Просьба уточнить, относится ли ваш ответ к Python 2, 3 или и тому и другому.
Ответы
Ответ 1
object
не реализует __eq__
, поэтому возвращается к сравнению сравнения id(x) == id(y)
по умолчанию, т.е. являются ли они одним и тем же экземпляром объекта (x is y
)?
Поскольку новый экземпляр создается каждый раз, когда вы вызываете object()
, my_object
никогда не сравнится с чем-либо, кроме самого себя.
Это относится как к файлам 2.x, так и 3.x:
# 3.4.0
>>> object().__eq__(object())
NotImplemented
# 2.7.6
>>> object().__eq__(object())
Traceback (most recent call last):
File "<pyshell#60>", line 1, in <module>
object().__eq__(object())
AttributeError: 'object' object has no attribute '__eq__'
* или, скорее, как roippi
answer указывает, вряд ли когда-либо, предполагая разумные реализации __eq__
в другом месте.
Ответ 2
object().__eq__
возвращает NotImplemented
singleton:
print(object().__eq__(3))
NotImplemented
По рефлексивным правилам богатых сравнений, когда возвращается NotImplemented
, проверяется "отраженная" операция. Поэтому, если у вас есть объект в RHS, который возвращает True
для этого сравнения, вы можете получить ответ True
, хотя LHS не реализовал сравнение.
class EqualToEverything(object):
def __eq__(self,other):
return True
ete = EqualToEverything()
ete == object() # we implemented `ete.__eq__`, so this is obviously True
Out[74]: True
object() == ete # still True due to the reflexive rules of rich comparisons
Out[75]: True
конкретный бит python 2:, если ни один объект не реализует __eq__
, тогда python переходит на проверку, реализует ли __cmp__
. Эквивалентные рефлексивные правила применяются здесь.
class ComparableToEverything(object):
def __cmp__(self,other):
return 0
cte = ComparableToEverything()
cte == object()
Out[5]: True
object() == cte
Out[6]: True
__cmp__
отсутствует в python 3.
В обоих python 2 и 3, когда мы исчерпываем все эти операторы сравнения и все NotImplemented
, окончательный откат проверяет личность. (a is b
)