为什么不调用__instancecheck__? [英] Why isn't __instancecheck__ being called?
问题描述
我有以下python3代码:
I have the following python3 code:
class BaseTypeClass(type):
def __new__(cls, name, bases, namespace, **kwd):
result = type.__new__(cls, name, bases, namespace)
print("creating class '{}'".format(name))
return result
def __instancecheck__(self, other):
print("doing instance check")
print(self)
print(other)
return False
class A(metaclass=BaseTypeClass):
pass
print(type(A))
print(isinstance(A(), A))
当我在Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
上运行它时,得到以下输出
and when I run it on Python 3.6.3 (v3.6.3:2c5fed8, Oct 3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
I get the following output
creating class 'A'
<class '__main__.BaseTypeClass'>
True
为什么不输出doing instance check
? __instancecheck__
说,文档方法需要在元类上定义,而不是在类本身上定义,这是我在这里所做的.我什至验证了自从打印creating class 'A'
以来正在使用元类.但是,当我调用isinstance
时,它似乎正在使用默认实现,而不是我在元类中定义的实现.
Why isn't it outputting doing instance check
? The documentation says the __instancecheck__
method needs to be defined on the metaclass and not the class itself, which I have done here. I even verify the metaclass is being used since creating class 'A'
is printed. However, when I call isinstance
it appears to be using the default implementation and not the one I defined in the metaclass.
我可能没有正确使用元类,但是我不知道自己在哪里弄错了.
I'm probably not using metaclasses correctly, but I can't figure out where I made my mistake.
推荐答案
isinstance
函数可以快速检查作为参数提供的实例的类型是否与该类的类型相同.如果是这样,它将提早返回,并且不会调用您的自定义__instancecheck__
.
The isinstance
function makes a quick check to see if the type of the instance supplied as an argument is the same as that of the class. If so, it returns early and doesn't invoke your custom __instancecheck__
.
此优化用于避免不必要时对__instancecheck__
(它是Pythonland代码)的昂贵调用.
This is an optimization used in order to avoid an expensive call to __instancecheck__
(it's Pythonland code) when it isn't required.
您可以在PyObject_IsInstance
,该函数处理CPython实现中的isinstance
调用:
/* Quick test for an exact match */
if (Py_TYPE(inst) == (PyTypeObject *)cls)
return 1;
当然,当该测试不是True
时,您的__instancecheck__
会正确触发:
Of course, your __instancecheck__
fires correctly when that test isn't True
:
>>> isinstance(2, A)
doing instance check
<class '__main__.A'>
2
False
I am not certain if this is implementation specific, I would of thought so, though, since there's no reference to this in the corresponding PEP section nor in the documentation on isinstance
.
有趣的是:issubclass
实际上并不这样.由于其实现,它始终调用__subclasscheck__
.不久前,我打开了一个问题.
Interesting aside: issubclass
actually doesn't behave this way. Due to its implementation it always calls __subclasscheck__
. I had opened an issue on this a while back which is still pending.
这篇关于为什么不调用__instancecheck__?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!