3

Look at the following code:

a = 3
type(a) == object
False
isinstance(a, object)
True

How is this to be explained?

halfer
  • 19,824
  • 17
  • 99
  • 186
user8270077
  • 4,621
  • 17
  • 75
  • 140

2 Answers2

3

Everything is an object in Python, which includes ints, strings, functions and classes. Therefore, isinstance(a, object) will return you True . But 3 is actually an integer, which is a sub_class create from object. Therefore type(a) can equal to int only.

I can give you an example.

Suppose we have two classes, Sub is a sub_class of Base.

class Base:
    def __init__(self):
        self.kappa='kappa'
class Sub(Base):
    def __init__(self):
        super().__init__()

obj=Base()
int_rino=Sub()


print(isinstance(obj, Base))
print(isinstance(obj, Sub))
print(isinstance(int_rino, Base))
print(isinstance(int_rino, Sub))


print(type(int_rino) == Base)

The result will be:

True
False
True
True
False
CharlesB
  • 86,532
  • 28
  • 194
  • 218
Marcus.Aurelianus
  • 1,520
  • 10
  • 22
2

This is a common construct in most object-oriented languages that support inheritance. When a child class (in your case int) inherits from a parent (in your case object), it is said to have an "is-a" relationship. That is, an int is a (or an) object.

This "is-a" relationship is what isinstance is checking. From the docs:

Return true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof.

There is a similar issubclass function to check the same relationship for a class instead of an instance of that class. In fact, in most cases, isinstance(x, y) == issubclass(type(x), y).

type returns the exact class that an object was constructed from. That means that checking type(3) == object is exactly equivalent to checking int == object. Hopefully you can see that that's unambiguously false.

On a related tangent, classes should always be the same reference within a given run of the interpreter, so you can use is instead of == for comparison. So type(3) is int will be true. That's how == is implemented for all the types you're ever likely to come across anyway.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Great answer, however do not oppose `class` and `instance` because classes are instance of Type – Florian Jul 13 '18 at 07:17
  • 1
    @Florian. I wouldn't say that I'm opposing instances and types. Of course you're right that all classes are an instance of their metaclass (which doesn't have to be `type` or even inherit from it). However, I feel that this is a level of pedantic detail OP does not need and possibly can't handle at the moment. Also, keep in mind that functions like `issubclass` and `isinstance` *require* a class or tuple of classes for their second argument. So classes, regardless of metaclass, do have a special purpose here. – Mad Physicist Jul 13 '18 at 07:23
  • I had already upvoted, and with the edit, it's perfectly clear and accurate :) I was not accurate, classes are instance of `Type` **by default**, but it's **not necessarily true**. (for example : in most API using metaclasses as factory pattern) – Florian Jul 13 '18 at 07:41
  • That gets me thinking now. I wonder if I can make a plain function into a metaclass by slapping on `__init__` and `__new__` attributes. – Mad Physicist Jul 13 '18 at 08:17