2

我正在寻找something以下代码,以便之后的检查在任何情况下都isinstance()可以评估为:True

i = WonderfulClass()
classinfo_of_i = something(i)
isinstance(i, classinfo_of_i) # must evaluate to True

如果type是您的答案,如果您解释原因,我将不胜感激。是type真正的对应物isinstance吗?或者,反过来问,你能想出一个isinstance(i, type(i))评估为 False 的情况吗?

这个问题出现在检查列表或集合的元素是否为单一类型的简单方法的上下文中?,我们必须遍历一个序列并检查所有序列元素是否属于同一类型。在这种情况下,元素将相互比较。这种比较可以基于type或基于isinstance

相关文件isinstance(object, classinfo):_

如果 object 参数是 classinfo 参数的实例,则返回 true

4

4 回答 4

6

“ type 是 isinstance 的真正对应物吗?或者,反过来问,你能想到 isinstance(i, type(i)) 评估为 False 的情况吗?”

我看不到任何isinstance(i, type(i))不会返回的情况True

type()检查并从实例返回类型对象,因此返回的值没有理由无法通过isinstance()检查。

深入 cPython 的源代码,我们看到后面的代码type()只是简单地返回了附加到实例的类型对象:

v = (PyObject *)o->ob_type;
Py_INCREF(v);
return v;

isintance() 代码做的第一件事是检查类型是否完全匹配(它稍后会继续匹配继承链中的类):

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;

请注意,这Py_TYPE只是一个返回与 .obj->ob_type的返回值匹配的宏type()。这在 Include/object.h 中定义为:

#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
于 2012-09-13T09:30:23.277 回答
2

type()返回预期的内容,但前提是您使用新样式类(继承自object)。

考虑以下:

>>> class WonderfulClass(object):
...     pass
...
>>> i = WonderfulClass()
>>> isinstance(i,type(i))
True
>>> type(i)
<class '__main__.WonderfulClass'>
>>> class AnotherClass:
...     pass
...
>>> z = AnotherClass()
>>> type(z)
<type 'instance'>
>>> isinstance(z,type(z))
True

因此,尽管isinstance检查会起作用,但值得注意的是差异。

于 2012-09-13T09:39:16.520 回答
2

首先,isinstance是为了处理继承。例如

>>> isinstance("asdfs", object)
True

这里字符串被认为是对象的一个​​实例,因为“str”类型是“object”类型的继承者。所以 type 不是 isinstance 的严格对应物。

一切都是python中的对象,因此, isinstance(anything, object) 应该为任何东西返回 True ,因此,数组中的所有值在它们的类层次结构中都有一个共同的祖先:对象。

如果您想直接引用更特殊的类型/将其存储在变量中并能够与之进行比较,types您可能会对模块感兴趣。

于 2012-09-13T09:44:58.703 回答
1
>>> class P:
...   pass
...
>>> p = P()
>>> type(p)
<type 'instance'>
>>> p.__class__
<class __main__.P at 0x015A6A78>

>>> class D(object):
...   pass
...
>>>
>>> d = D()
>>> type(d)
<class '__main__.D'>
>>> d.__class__
<class '__main__.D'>
于 2012-09-13T09:43:00.467 回答