Why Is 'Object' an Instance of 'Type' and 'Type' an Instance of 'Object'

Why is `object` an instance of `type` and `type` an instance of `object`?

Answers to all your questions can be found in this book: Python Types and Objects

UPD: another link to the book. Let me know if it dies too.

The most important parts to answer your questions:

  • Has the type/class of an object also to be an object itself?

Yes, according to the Rule 1 from chapter 1:

"Everything is an object... Any classes that we define are objects, and of course, instances of those classes are objects as well."

  • Which one is the real base class object or type?

From chapter 2:

"These two objects are primitive objects in Python. We might as well have introduced them one at a time but that would lead to the chicken and egg problem - which to introduce first? These two objects are interdependent - they cannot stand on their own since they are defined in terms of each other."

Also Luciano Ramalho in his book "Fluent Python" says that this relation can't be expressed in Python (chapter 21):

"The classes object and type have a unique relationship: object is an
instance of type, and type is a subclass of object. This relationship
is "magic": it cannot be expressed in Python because either class would
have to exist before the other could be defined. The fact that type is
an instance of itself is also magical."

So, for your question:

  • How can a class (type) be an instance of itself?

Luciano says that it can't be expressed in Python too.

  • Is there a possibility to illustrate the relation between the object and the type class?

Many thanks to the author who made this illustration in сhapter 3:

relation between object, type and other classes

The instance relation between type and object in python?

Useful Definition

isinstance(object, classinfo)

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

https://docs.python.org/3.9/library/functions.html?highlight=isinstance#isinstance

1) type is an instance of object

  • All data is represented by objects and object is a base for all classes

Objects are Python’s abstraction for data. All data in a Python program is represented by objects or by relations between objects.

https://docs.python.org/3.9/reference/datamodel.html#types

object is a base for all classes.

https://docs.python.org/3.9/library/functions.html?highlight=object#object

  • type inherits from object (https://docs.python.org/3.9/library/functions.html?highlight=object#type) so type is both a subclass and also an instance of object using the isinstance description.

2) object is an instance of type

  • object is a type object. In other words, object is of type, type

Type Objects

Type objects represent the various object types. An object’s type is accessed by the built-in function type()

https://docs.python.org/3.9/library/stdtypes.html?highlight=subclass#type-objects

  • type(object) # returns type

  • type(type) # returns type

  • object.__class__ # returns type

  • type.__class__ # returns type

  • Which helps us understand how isInstance(object, type) will return True.

  • An intuitive way to think about this is that the object object is of type type but object is not a subclass of type because it doesn't inherit from type

Meaning of Instances of types are called objects

In simple language when it says : Instances of types are called objects it means, when you have defined a prototype or a blueprint and you want to use that blueprint you need to declare an object of that type.

You have different types.

  1. Primitive data type like int, long, char, short etc
  2. User defined data types like Class, Structure etc
  3. Derived data types like Function Array Pointers etc

And to use any data type you need to have an object for that type.

For example : Primitive data type , you have int i;
When you declare this way, you mean you need a variable/object of 4 bytes of memory.
So here i is your object. So you cannot use the object i without the type.
Similarly you may require different objects for different types.

For non-primitive types also the same logic apply.

Suppose you have a class as below :

class Student {
public:
int rollNum;
String name;

}

This is your blueprint, your type. When you need to use class variables you need to create an object for your type. like below :

Student s;

And you will be able to access the variables and assign them values according to your wish.

s.rollNum = 10;
s.name = "Martin";

So your object is : s which is a type of Student

More from a blog post on "Class vs Object vs Instance":

In short, An object is a software bundle of related state and
behavior. A class is a blueprint or prototype from which objects are
created. An instance is a single and unique unit of a class.

Object Real world objects shares 2 main characteristics, state and behavior. Human have state (name, age) and behavior (running,
sleeping). Car have state (current speed, current gear) and state
(applying brake, changing gear). Software objects are conceptually
similar to real-world objects: they too consist of state and related
behavior. An object stores its state in fields and exposes its
behavior through methods.

Class Class is a “template” / “blueprint” that is used to create objects. Basically, a class will consists of field, static field,
method, static method and constructor. Field is used to hold the state
of the class (eg: name of Student object). Method is used to represent
the behavior of the class (eg: how a Student object going to
stand-up). Constructor is used to create a new Instance of the Class.

Instance An instance is a unique copy of a Class that representing an Object. When a new instance of a class is created, the Compiler or
JVM (for java) will allocate a room of memory for that class instance.

What are the differences between type() and isinstance()?

To summarize the contents of other (already good!) answers, isinstance caters for inheritance (an instance of a derived class is an instance of a base class, too), while checking for equality of type does not (it demands identity of types and rejects instances of subtypes, AKA subclasses).

Normally, in Python, you want your code to support inheritance, of course (since inheritance is so handy, it would be bad to stop code using yours from using it!), so isinstance is less bad than checking identity of types because it seamlessly supports inheritance.

It's not that isinstance is good, mind you—it's just less bad than checking equality of types. The normal, Pythonic, preferred solution is almost invariably "duck typing": try using the argument as if it was of a certain desired type, do it in a try/except statement catching all exceptions that could arise if the argument was not in fact of that type (or any other type nicely duck-mimicking it;-), and in the except clause, try something else (using the argument "as if" it was of some other type).

basestring is, however, quite a special case—a builtin type that exists only to let you use isinstance (both str and unicode subclass basestring). Strings are sequences (you could loop over them, index them, slice them, ...), but you generally want to treat them as "scalar" types—it's somewhat incovenient (but a reasonably frequent use case) to treat all kinds of strings (and maybe other scalar types, i.e., ones you can't loop on) one way, all containers (lists, sets, dicts, ...) in another way, and basestring plus isinstance helps you do that—the overall structure of this idiom is something like:

if isinstance(x, basestring)
return treatasscalar(x)
try:
return treatasiter(iter(x))
except TypeError:
return treatasscalar(x)

You could say that basestring is an Abstract Base Class ("ABC")—it offers no concrete functionality to subclasses, but rather exists as a "marker", mainly for use with isinstance. The concept is obviously a growing one in Python, since PEP 3119, which introduces a generalization of it, was accepted and has been implemented starting with Python 2.6 and 3.0.

The PEP makes it clear that, while ABCs can often substitute for duck typing, there is generally no big pressure to do that (see here). ABCs as implemented in recent Python versions do however offer extra goodies: isinstance (and issubclass) can now mean more than just "[an instance of] a derived class" (in particular, any class can be "registered" with an ABC so that it will show as a subclass, and its instances as instances of the ABC); and ABCs can also offer extra convenience to actual subclasses in a very natural way via Template Method design pattern applications (see here and here [[part II]] for more on the TM DP, in general and specifically in Python, independent of ABCs).

For the underlying mechanics of ABC support as offered in Python 2.6, see here; for their 3.1 version, very similar, see here. In both versions, standard library module collections (that's the 3.1 version—for the very similar 2.6 version, see here) offers several useful ABCs.

For the purpose of this answer, the key thing to retain about ABCs (beyond an arguably more natural placement for TM DP functionality, compared to the classic Python alternative of mixin classes such as UserDict.DictMixin) is that they make isinstance (and issubclass) much more attractive and pervasive (in Python 2.6 and going forward) than they used to be (in 2.5 and before), and therefore, by contrast, make checking type equality an even worse practice in recent Python versions than it already used to be.

The difference between Classes, Objects, and Instances

Java (and any other programming language) is modeled in terms of types and values. At the theoretical level, a value is a representation for some quantum of information, and a type is a set of values. When we say value X is an instance of type Y, we are simply saying that X is a member of the set of values that is the type Y.

So that's what the term "instance" really means: it describes a relationship not a thing.

The type system of the Java programming language supports two kinds of types, primitive types and reference types. The reference types are further divided into the classes and array types. A Java object is an instance of a reference type.

An object is a class instance or an array. (JLS 4.3.1)

That's the type theoretic view.

In practice, most Java developers treat the words "instance" and "object" as synonyms. (And that includes me then I'm trying to explain something quickly.) And most developers use the word "value" rather than "instance" to refer to an instance of a primitive type.

Python 3: How can object be instance of type?

This is one of the edge cases in Python:

  • Everything in Python is an object, so since object is the base type of everything, type (being something in Python) is an instance of object.
  • Since object is the base type of everything, object is also a type, which makes object an instance of type.

Note that this relationship is nothing you can replicate with your own things in Python. It’s a single exception that is built into the language.


On the implementation side, the two names are represented by PyBaseObject_Type (for object) and PyType_Type (for type).

When you use isinstance, the type check—in the very last step, after everything else has failed—is done by type_is_subtype_base_chain:

type_is_subtype_base_chain(PyTypeObject *a, PyTypeObject *b)
{
do {
if (a == b)
return 1;
a = a->tp_base;
} while (a != NULL);

return (b == &PyBaseObject_Type);
}

This essentially keeps going up the type hierarchy of a and checks the resulting type against b. If it cannot find one, then the last resort is to check whether b is actually object in which case the function returns true: since everything is an object. So the “everything is an instance of object” part is actually hardcoded into the instance check.

And as for why object is a type, this is actually even simpler because it’s simply defined that way in the declaration of PyBaseObject_Type:

PyTypeObject PyBaseObject_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"object", /* tp_name */
sizeof(PyObject), /* tp_basicsize */

The PyVarObject_HEAD_INIT essentially sets the core type information stuff, including the base type, which is PyType_Type.

There are actually two more consequences of this relationship:

  • Since everything is an object, object is also an instance of object: isinstance(object, object)
  • Since PyType_Type is also implemented with the same PyVarObject_HEAD_INIT, type is also a type: isinstance(type, type).

How to create a new object instance from a Type

The Activator class within the root System namespace is pretty powerful.

There are a lot of overloads for passing parameters to the constructor and such. Check out the documentation at:

http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx

or (new path)

https://learn.microsoft.com/en-us/dotnet/api/system.activator.createinstance

Here are some simple examples:

ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);

ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");


Related Topics



Leave a reply



Submit