代码之家  ›  专栏  ›  技术社区  ›  sanyassh Khushboo Tahir

__instancecheck__;[duplicate]的最小工作示例

  •  1
  • sanyassh Khushboo Tahir  · 技术社区  · 5 年前

    我试图使我的类看起来像一个不同的对象,以避免在我使用的包中进行惰性类型检查。更具体地说,我试图使我的对象显示为另一个对象的实例( tuple 在我的情况下)在现实中,这甚至不是它的派生。

    为了实现这一点,我计划覆盖 __isinstance__ 根据 docs ,应该做我想做的事。然而,我似乎不知道该怎么做,因为我的尝试没有成功。

    这是一个SSCCE 应该 制作 isinstance 回来 False 在所有情况下,但并非如此。

    class FalseInstance(type):
        def __instancecheck__(self, instance):
            return False
    
    class Foo(metaclass=FalseInstance):
        pass
    
    g = Foo()
    isinstance(g, Foo)
    > True
    

    我做错了什么?

    0 回复  |  直到 6 年前
        1
  •  8
  •   user2357112    6 年前

    除了与 __metaclass__ 以及精确类型匹配的快速路径, __instancecheck__ 和你想做的相反。一个班级的 __instancecheck__ 检查其他对象是否被视为该类的虚拟实例,而不是该类的实例是否被视为其他类的虚拟实例。

    如果你想让你的对象撒谎 isinstance 检查(你真的不应该),那么方法就是撒谎 __class__ ,而不是实施 __instancecheck__ .

    class BadIdea(object):
        @property
        def __class__(self):
            return tuple
    
    print(isinstance(BadIdea(), tuple)) # prints True
    

    顺便说一句,如果你想得到一个对象的实际类型,使用 type 而不是检查 __阶级__ 存在 .

        2
  •  7
  •   DeepSpace    6 年前

    如果你在里面加了一张照片 FalseInstance.__instancecheck__ 您将看到它甚至没有被调用。然而,如果你打电话 isinstance('str', Foo) 那你就会明白了 举个例子__instancecheck__ 确实会被调用。

    这是由于优化了 isinstance 的实现立即返回 True 如果 type(obj) == given_class :

    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;
        .
        .
        .
    }
    

    From Python's source code