Are classobjects singletons?
如果我们有
这是一个反例,但它是一个骗局:
1 2 3 4 5 6 7 8 9 10 11 12 13 | >>> 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) |
我无法创建这样的反例:
1 2 3 4 5 6 7 8 | >>> 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或
如果没有,这是由语言保证的还是在任何地方记录的?
后记:
1 2 3 | # thing.py class A: pass |
最后,这就是为我澄清真实行为的原因(它支持BLCKKNGHT答案中的主张)
1 2 3 4 5 6 7 8 9 | >>> 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) |
。
因此,尽管使用
我不知道关于
1 2 3 4 5 6 7 8 9 10 11 | static PyObject* type_richcompare(PyObject *v, PyObject *w, int op) { ... /* Compare addresses */ vv = (Py_uintptr_t)v; ww = (Py_uintptr_t)w; switch (op) { ... case Py_EQ: c = vv == ww; break; |
在cpython 3.5中,
1 2 3 | PyTypeObject PyType_Type = { ... 0, /* tp_richcompare */ |
号
不,除了用元类
但是这种行为并不是类特有的。它是没有在类中定义
至于在不同的内存位置获得对同一类的两个不同引用,由于Python的对象语义,这实际上是不可能的。对象的内存位置是其标识(至少在cpython中)。另一个具有相同内容的类可以存在于其他地方,但就像在您的