为什么不调用__instancecheck__? [英] Why isn't __instancecheck__ being called?

查看:36
本文介绍了为什么不调用__instancecheck__?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆