Introduction to classes and type in Python

In this post, we are going to discuss Python classes and type.

Since Python is an object-oriented language, everything is an object and a descendant of a class.

But, what you might not know, is that every class is itself descendant of another class known as type.

In Python, we have the built-in type() function that lets you view the type of any object in Python.

Take a look at the example below:

name = "Mike"
print(type(name))

We see that the type of name is a string. Now, let’s try building our own class.

We are going to build a class called Fruit and instantiate descendant fruits from our Fruit class.

class Fruit:
def __init__(self, color, shape):
self.color = color
self.shape = shape
def show_characteristics(self):
characteristics = [self.shape, self.color]
return characteristics

We know that we can instantiate a fruit from our Fruit class and we will have descendant.

Earlier, we mentioned that even classes are descendant of another class above them. This means that strings, integers, and our Fruit class has a higher class above it.

The type class

When you inspect the type of an objectlike an instance of our Fruit, or a string object like our name using the type() function, it will return the parent of that object to you.

But what will happen if we try to get the type of our Fruit class itself?

class Fruit:
def __init__(self, color, shape):
self.color = color
self.shape = shape
def show_characteristics(self):
characteristics = [self.shape, self.color]
return characteristics
print(type(Fruit))

You will get <class 'type'> as an output. If you try to execute it on str, int, type, or other Python classes, you will get <class 'type'>.

This is because all classes and objects inherit from the type class above everything else. Therefore, it is possible to re-create our fruit class directly from type.

Creating a class with type

If you look for type in the Python help console, you will see a description of the arguments that type takes in order to create a class.

It is worth noting that type takes either 1 or 3 arguments. When a single argument is passed, it will return the class from which the object inherits. When 3 arguments are passed, it returns new class to you with the characteristics and attributes you passed in as last argument. More on this below.

  • The first argument it takes is the name of the class you are creating.
  • The second argument is the bases from which your class would inherit. Say you are creating a new class that inherits from str, then you would pass a tuple as the second argument.
  • The third argument is a dictionary that will hold the methods and variables inside our class.

Now, let’s create our class. We are going to recreate the same Fruit class as above.

def fruit_init(self, shape, color):
self.shape = shape
self.color = color
def show_characteristics(self):
characteristics = [self.color, self.shape]
return characteristics
fruit_class = type("FruitClass", (), {"__init__": fruit_init, "show_characteristics": show_characteristics})

Let’s explore what is happening here.

We are creating a class called FruitClass, which inherits from no other class (thus the empty tuple). Our class has some methods like init and show_characteristics, which map to the functions we created above.

We created those functions above because it will be hard to fit them into the dictionary, but you could make use of lambda expressions there.

What we end up with is a class that we can use. Let’s try it out.

def fruit_init(self, shape, color):
self.shape = shape
self.color = color
def show_characteristics(self):
characteristics = [self.color, self.shape]
return characteristics
fruit_class = type("FruitClass", (), {
"__init__": fruit_init, "show_characteristics": show_characteristics})
orange = fruit_class("spherical", "orange")
print(orange.show_characteristics())

How is this useful?

If you have knowledge of the above underlying functioning in Python, you will be able to better understand the behavior of objects and some classes in Python. With this, you can even define your own blueprints for creating other classes and types, just by creating a class that inherits from the type class above.

This will give you the power to be able to define your own behavior for objects, and even set rules on what happens when a new object is created.

Free Resources