Python: can isinstance (i, type (i)) for False?

I am looking for something in the following code snippet, so checking isinstance() after this evaluates to True anyway:

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

If type is your answer, I would appreciate it if you could explain why. Is type real analog of isinstance ? Or, by asking the other way around, can you imagine the case when isinstance(i, type(i)) is evaluated as a lie?

This question arose in the context of an easy way to check if list or set items are single types? where we need to go through the sequence and check if all elements of the sequence are of the same type. In this context, the elements will be compared with each other. This comparison can be based on type or based on isinstance .

Relevant documentation regarding isinstance(object, classinfo) :

Returns true if the object argument is an instance of the info class. Argument

+2
source share
4 answers

"Is type a real analogue of isinstance? Or, I asked the other way around, can you imagine the case when isinstance (i, type (i)) is False?"

I do not see a situation in which isinstance(i, type(i)) will not return True .

type() checks and returns the type object from the instance, so there is no reason the return value will complete the isinstance() check.

Digging into the cPython source, we see that the code for type() just returns a type object attached to the instance:

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

while the first thing that isintance () code does is check if the types match exactly (later it will go into correspondence with the classes in the inheritance chain):

 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 just a macro that returns obj->ob_type , which corresponds to the return value of type() . This is defined in Include / object.h as:

 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 
+6
source

type() returns the expected, but only if you use new style classes (inherit from 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, while the isinstance check will work, it's worth noting the differences.

+2
source

First of all, isinstance is for inheritance. For instance.

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

Here the string was considered an instance of the object, since the type "str" ​​is the descendant of the type "object". Thus, a type is not the strict equivalent of isinstance.

Everything is an object in python, so isststance (anything, an object) should return True for anything, and thus all values ​​in your array have a common ancestor in the class hierarchy: object.

If you want to directly refer to a more special type / store it in a variable and be able to compare with it, the types module may interest you.

+2
source
 >>> 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'> 
+1
source

Source: https://habr.com/ru/post/1433964/


All Articles