我在以下代码中寻找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的情况吗?
这个问题出现在the simple way to check if the elements of a list or set are single type?的上下文中,我们必须经历一个序列并检查所有序列元素是否属于同一类。在这种情况下,元素将相互比较。此比较可以基于type
或基于isinstance
。
关于isinstance(object, classinfo)
的相关documentation:
如果object参数是classinfo的实例,则返回true 参数
答案 0 :(得分:6)
“类型是isinstance的真正对应物吗?或者,反过来问,你能想到isinstance(i,type(i))评估为False的情况吗?”
我看不到isinstance(i, type(i))
不会返回True
的任何情况。
type()
检查并返回实例中的类型对象,因此没有理由为返回的值无法通过isinstance()
检查。
深入研究cPython的源代码,我们看到code behind type()
只返回附加到实例的类型对象:
v = (PyObject *)o->ob_type;
Py_INCREF(v);
return v;
虽然isintance() code做的第一件事就是检查类型是否完全匹配(后来会继续匹配继承链中的类):
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()
的返回值相匹配。这是defined in Include/object.h:
#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
答案 1 :(得分: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
检查有效,但值得注意的是差异。
答案 2 :(得分:2)
首先,isinstance
旨在处理继承。例如。
>>> isinstance("asdfs", object)
True
这里的字符串被认为是对象的实例,因为“str”类型是“对象”类型的继承人。所以类型不是isinstance的严格对应。
所有东西都是python中的一个对象,因此,isinstance(任何东西,对象)应该为任何东西返回True,因此,数组中的所有值在它们的类层次结构中都有一个共同的祖先:object。
如果您想直接引用更特殊的类型/将其存储在变量中并且能够与其进行比较,types
模块可能会对您感兴趣。
答案 3 :(得分: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'>