__instancecheck__ - 覆盖显示无效 - 我做错了什么?
__instancecheck__ - overwrite shows no effect - what am I doing wrong?
我试图让我的 class 显示为一个不同的对象,以规避我正在使用的包中的延迟类型检查。更具体地说,我试图让我的对象显示为另一个对象的实例(tuple
在我的例子中),而实际上它甚至不是那个对象的派生。
为了实现这一点,我计划覆盖 __isinstance__
方法,根据 docs,该方法应该完全符合我的要求。但是,我似乎不明白该怎么做,因为我的尝试一直没有成功。
这是一个 SSCCE,应该 在所有情况下都isinstance
return False
但是没有。
class FalseInstance(type):
def __instancecheck__(self, instance):
return False
class Foo(metaclass=FalseInstance):
pass
g = Foo()
isinstance(g, Foo)
> True
我做错了什么?
如果您在 FalseInstance.__instancecheck__
中添加打印,您会发现它甚至没有被调用。但是,如果您调用 isinstance('str', Foo)
,那么您会看到确实调用了 FalseInstance.__instancecheck__
。
这是由于 isinstance
实施中的优化,如果 type(obj) == given_class
:
立即 returns True
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
_Py_IDENTIFIER(__instancecheck__);
PyObject *checker;
/* Quick test for an exact match */
if (Py_TYPE(inst) == (PyTypeObject *)cls)
return 1;
.
.
.
}
除了 __metaclass__
的问题和精确类型匹配的快速路径之外,__instancecheck__
的工作方向与您尝试做的相反。 class 的 __instancecheck__
检查其他对象是否被认为是那个 class 的虚拟实例,而不是那个 class 的实例是否被认为是其他 class 的虚拟实例es.
如果你想让你的对象在 isinstance
检查中谎报它们的类型(你真的不应该这样做),那么做到这一点的方法是谎报 __class__
,而不是实现 __instancecheck__
.
class BadIdea(object):
@property
def __class__(self):
return tuple
print(isinstance(BadIdea(), tuple)) # prints True
顺便说一句,如果你想获得对象的实际类型,请使用 type
而不是检查 __class__
或 isinstance
.
我试图让我的 class 显示为一个不同的对象,以规避我正在使用的包中的延迟类型检查。更具体地说,我试图让我的对象显示为另一个对象的实例(tuple
在我的例子中),而实际上它甚至不是那个对象的派生。
为了实现这一点,我计划覆盖 __isinstance__
方法,根据 docs,该方法应该完全符合我的要求。但是,我似乎不明白该怎么做,因为我的尝试一直没有成功。
这是一个 SSCCE,应该 在所有情况下都isinstance
return False
但是没有。
class FalseInstance(type):
def __instancecheck__(self, instance):
return False
class Foo(metaclass=FalseInstance):
pass
g = Foo()
isinstance(g, Foo)
> True
我做错了什么?
如果您在 FalseInstance.__instancecheck__
中添加打印,您会发现它甚至没有被调用。但是,如果您调用 isinstance('str', Foo)
,那么您会看到确实调用了 FalseInstance.__instancecheck__
。
这是由于 isinstance
实施中的优化,如果 type(obj) == given_class
:
True
int
PyObject_IsInstance(PyObject *inst, PyObject *cls)
{
_Py_IDENTIFIER(__instancecheck__);
PyObject *checker;
/* Quick test for an exact match */
if (Py_TYPE(inst) == (PyTypeObject *)cls)
return 1;
.
.
.
}
除了 __metaclass__
的问题和精确类型匹配的快速路径之外,__instancecheck__
的工作方向与您尝试做的相反。 class 的 __instancecheck__
检查其他对象是否被认为是那个 class 的虚拟实例,而不是那个 class 的实例是否被认为是其他 class 的虚拟实例es.
如果你想让你的对象在 isinstance
检查中谎报它们的类型(你真的不应该这样做),那么做到这一点的方法是谎报 __class__
,而不是实现 __instancecheck__
.
class BadIdea(object):
@property
def __class__(self):
return tuple
print(isinstance(BadIdea(), tuple)) # prints True
顺便说一句,如果你想获得对象的实际类型,请使用 type
而不是检查 __class__
或 isinstance
.