Если мы имеем x = type(a)
и x == y
, обязательно ли это означает, что x is y
?
Вот контрпример, но это чит:
>>> class BrokenEq(type):
... def __eq__(cls, other):
... return True
...
>>> class A(metaclass=BrokenEq):
... pass
...
>>> a = A()
>>> x = type(a)
>>> x == A, x is A
(True, True)
>>> x == BrokenEq, x is BrokenEq
(True, False)
И я не мог создать контрпример таким образом:
>>> A1 = type('A', (), {})
>>> A2 = type('A', (), {})
>>> a = A1()
>>> x = type(a)
>>> x == A1, x is A1
(True, True)
>>> x == A2, x is A2
(False, False)
Чтобы прояснить мой вопрос - без переопределения операторов равенства сделать что-то безумное, возможно ли, чтобы класс существовал в двух разных ячейках памяти или система импорта каким-то образом предотвратила это?
Если да, то как мы можем продемонстрировать это поведение - например, делать странные вещи с помощью reload или __import__
?
Если нет, это гарантируется языком или документировано где-нибудь?
Эпилог
# thing.py
class A:
pass
Наконец, это то, что прояснило реальное поведение для меня (и оно поддерживает утверждения в ответе Блеккна)
>>> import sys
>>> from thing import A
>>> a = A()
>>> isinstance(a, A), type(a) == A, type(a) is A
(True, True, True)
>>> del sys.modules['thing']
>>> from thing import A
>>> isinstance(a, A), type(a) == A, type(a) is A
(False, False, False)
Итак, хотя код, который использует importlib.reload
, может нарушить проверку типов по идентификатору класса, он также будет разбит isinstance
.