简体   繁体   English

Python:可以isinstance(i,type(i))计算为False?

[英]Python: can isinstance(i, type(i)) evaluate to False?

I am looking for something in the following piece of code so that the isinstance() check afterwards evaluates to True in any case: 我在下面的代码中寻找something ,以便在任何情况下isinstance()检查后评估为True

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

If type is your answer, I'd be grateful if you explained why. 如果type是你的答案,如果你解释原因,我将不胜感激。 Is type the real counterpart of isinstance ? typeisinstance的真正对应物吗? Or, asked the other way round, can you think of a case where isinstance(i, type(i)) evaluates to False? 或者,反过来问,你能想到isinstance(i, type(i))评估为False的情况吗?

This question arose in the context of the simple way to check if the elements of a list or set are single type? 这个问题出现在检查列表或集合的元素是否是单一类型的简单方法的上下文中 , where we have to go through a sequence and check if all the sequence elements are of the same kind. ,我们必须通过序列并检查所有序列元素是否属于同一类型。 In this context, elements will be compared to each other. 在这种情况下,元素将相互比较。 This comparison could be based on type or based on isinstance . 该比较可以基于type或基于isinstance

Relevant documentation regarding isinstance(object, classinfo) : 有关isinstance(object, classinfo)相关文档

Return true if the object argument is an instance of the classinfo argument 如果object参数是classinfo参数的实例,则返回true

"Is type the real counterpart of isinstance? Or, asked the other way round, can you think of a case where isinstance(i, type(i)) evaluates to False?" “类型是isinstance的真正对应物吗?或者,反过来问,你能想到isinstance(i,type(i))评估为False的情况吗?”

I can't see any situation where isinstance(i, type(i)) would not return True . 我看不到isinstance(i, type(i))不会返回True任何情况。

type() inspects and returns the type object from an instance so there's no reason why the returned value would fail the isinstance() check. type()检查并返回实例中的类型对象,因此没有理由为返回的值无法通过isinstance()检查。

Digging into the source of cPython, we see that the code behind type() simply returns the type object attached to the instance: 深入研究cPython的源代码,我们看到type()后面代码只返回附加到实例的类型对象:

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

while the first thing that the isintance() code does is check if the types match exactly (it would later move on to match against classes in the chain of inheritance): 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;

Note that Py_TYPE is simply a macro that returns obj->ob_type which matches the return value of type() . 请注意, Py_TYPE只是一个返回obj->ob_type的宏,它与type()的返回值匹配。 This is defined in Include/object.h as: 在Include / object.h中定义为:

#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)

type() returns what is expected, but only if you use new style classes (inherit from object ). type()返回预期的内容,但前提是您使用新样式类(从object继承)。

Consider the following: 考虑以下:

>>> 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

So although the isinstance check will work, its worth noting the differences. 因此,虽然isinstance检查将起作用,但值得注意的是差异。

First of all, isinstance is meant to deal with inheritance. 首先, isinstance意味着处理继承。 Eg 例如

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

Here a string was considered an instance of object, as "str" type is a heir of "object" type. 这里一个字符串被认为是一个对象的实例,因为“str”类型是“对象”类型的继承人。 So type is not a strict counterpart to isinstance. 所以类型不是isinstance的严格对应物。

Everything is an object in python, so, isinstance(anything, object) should return True for anything and, thus, all the values in your array have a common ancestor in their class hierarchy: object. 一切都是python中的一个对象,因此,isinstance(任何东西,对象)应该为任何东西返回True,因此,数组中的所有值在它们的类层次结构中都有一个共同的祖先:object。

If you'd like to directly refer to a more special type/store it in a variable and be able to compare to it, types module might be of interest to you. 如果您想直接引用更特殊的类型/将其存储在变量中并且能够与它进行比较,那么您可能会对types模块感兴趣。

>>> 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'>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM