在python中自定义__instancecheck__

Ank*_*wal 2 python

为什么这个打印是假的?

#! /usr/bin/env python

class A(object):
    def __instancecheck__(self,arg):
        print self, type(self), arg , type(arg)

if __name__ == '__main__':
    a = A()
    print isinstance(a,a)
Run Code Online (Sandbox Code Playgroud)

得到:

$ ./isinstancecheck.py 
<__main__.A object at 0x7f0574198b90> <class '__main__.A'> <__main__.A object at     0x7f0574198b90> <class '__main__.A'>
False
Run Code Online (Sandbox Code Playgroud)

fal*_*tru 5

根据文档,__instancecheck__应该返回True或False.

但是,A.__instancecheck__在你的代码中确实返回Nothing; 没有隐含地返回; None被视为错误; 所以False打印出来.

  • @abc,你不是直接调用`__instancecheck__`.(它由`isinstance`在内部调用).在`__instancecheck__`的末尾添加`return True`,然后尝试`print isinstance(a,...)`. (3认同)
  • @abc `isinstance` 将 `__instancecheck__` 的结果强制为 bool。 (2认同)

wim*_*wim 5

魔法__instancecheck__应该在元类上定义,而不是在类本身上定义。请参阅文档

请注意,这些方法是根据类的类型(元类)查找的。它们不能被定义为实际类中的类方法。

您所看到的奇怪行为是因为放错了isinstance参数。你写了:

isinstance(a, a)
Run Code Online (Sandbox Code Playgroud)

但实际上应该是:

isinstance(a, A)
Run Code Online (Sandbox Code Playgroud)

现在,这是错误的喜剧:如果您错误地定义__instancecheck__为普通类上的方法,则该类的实例可能会意外地用作第二个参数isinstance(通常第二个参数将是类对象)。Python 并不真正关心第二个参数的类型是类还是元类,因为这只是实际的鸭子类型。

请注意,isinstance将 的返回值强制__instancecheck__为布尔值。直接调用 witha.__instancecheck__(a)将返回None.