Tutorials
python

Type Checking in Python

Learn about type checking, different types of the type system in various languages along with duck typing, and type hinting.

The help of its own Interpreter does type checking in Python. Since Python is a dynamic language, it doesn't force the user to enforce the type of the objects, which can lead to bugs, and errors will be hard to find. To overcome this, Python can be used in conjunction with various other tools and implement features of static type checking along with its own Duck Typing.

There are two different types of type systems followed by different programming languages, which are shown below.

  1. Static Typed Language
  2. Dynamic Typed Language

Static Typed Language

The type checking of the variable type is done at compile-time. Also, the type system of the language forces to explicitly declare the 'data-type' of the variable before its usage. The programming languages which are statically typed are: Scala, Java, C++, etc.
For example, the declaration of String in Scala is defined below:
var myCar:String = "Mercedes";
The above code shows that the variable name 'myCar' is explicitly declared as 'String' data-type with the value as 'Mercedes'.

Dynamic Typed Language

The type checking of the variable type is done at run-time. Also, the type system of the language doesn't force to explicitly declare the 'data-type' of the variable before its usage. The programming languages which are dynamically typed are: Python, Javascript, Ruby, etc.
For example, the String in Python is defined below:
myCar = "Mercedes"
The above code shows that the variable name 'myCar' doesn't need to be explicitly declared.

'type()' and 'isinstance()' in Python

The variable types can be known using Python's own 'type()'. The 'type()' can be used at runtime for the debugging purpose to identify the exact variable types in the program. Let's look at the type of some variables in the example below.

my_var = 12
print(type(my_var))

The above code will give output as 'int'. Since the data type of the variable is integer where 'type()' plays a role in identifying it.

The 'insinstance('obj','class')' of Python can be used to know whether the 'obj', which is the object is the instance of the class or not. The returned output value is boolean can be one of True or False.

my_var = "Hello"
print(isinstance(my_var,str))

The above code will give output as True. Since the data type of the variable is a string, where 'isinstance()' plays a role in identifying it.

Duck typing in Python

There is a popular principle in Python, "If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck." Simply the principle is saying that the types of object or class don't matter, but object needs to contains similar methods and properties, then the object can be used for a particular purpose.
Let's look at an example to clarify the above statement in more detail.

Let's look at the below example, where there are two classes 'Duck' and 'Human'. Also, Duck is the class which contains methods as a quack and fly. Similarly, Human is a class with its own set of methods 'quack' and 'fly'. The Duck and Human are a different class and also a different object or type. However, Human contains similar methods as 'fly' and 'quack' in Duck. There is also a method 'fly_quack', which mostly resembles with the 'Duck' than 'Human' because it can fly and quack.

class Duck:
    def quack(self):
        print('Quack')
    def fly(self):
        print('Flap')
class Human:
    def quack(self):
        print('Trying to Quack like a duck')
    def fly(self):
        print('Spreading my arm to flap like a duck')      
def fly_quack(thing):
    thing.quack()
    thing.fly()

Let's make an instance of 'Duck' as du and pass to function 'fly_quack(du)'. Similarly, for Human instance 'h' is made and pass to function 'fly_quack(h)'.

du = Duck()
fly_quack(du)
h = Human()
fly_quack(h)

The output of the above code is below:

Trying to Quack like a duck
Spreading my arm to flap like a duck
Quack
Flap

Since the class, 'Human' is a different class than 'Duck', but the Python does call the function 'fly_quack' for human too. Though object types were different since the 'Human' has similar quack and fly methods, it behaves and provides the method required.

Type Hint and mypy

There is a powerful aspect of Dynamic typed Language like Python, which helps the code with accessibility and readable, but there are some downsides too. One of the downsides is to find the run time errors because Python doesn't enforce the type of the variable, or it is Dynamic typed language. The result of this can produce error and bugs, which will be difficult to find when the code length becomes larger and larger.

Python has implemented Type Hints from version 3.5. The older version might not support the functionality of TypeHints.

You'll see the simple example of without type hinting and mypy.

The function below is for the subtraction of an integer value, which subtracts two integers and returns the value.

def sub_this(x,y):
    return 'Subtraction'
print(sub_this(8,'hello'))

Here the function above needs to accept two integers 'x' and 'y', but since the rules are not imposed, can take any data type. Also, the return value can be anything where the 'str' value('Subtraction') is returned, but expected was 'int'.

Let's see the similar implementation of the above program, but by using type hints and 'mypy', which can help to implement static type checking and reduce error and bugs in the program quite easily.

'mypy' is a python module which helps in a static type checking, which uses the Python's own dynamic checking or duck typing with the type-hinting.

You need to install 'mypy' packages
pip install mypy

You can create a file named 'mypy_example.py' in your local machine and type the following code.
The below code is a simple program that accepts two integers as an input in the parameter and after '->' shows the returned data type, which is also an 'int'. However, the function needs to return int, but string 'Subtracted two integers' is returned.

def sub_this(x:int,y:int) -> int:
    return 'Subtracted two integers'
print(sub_this(8,4))

Run your above code in the terminal with the following code.
mypy mypy_example.py

Then the error will be shown, which indicates that the unexpected return value "str" is found and needs to be resolved with "int".

Let's change the return type to be the subtraction of the two integers so that the integer value gets returned.

def sub_this(x:int,y:int) -> int:
    return x - y
print(sub_this(8,4))

The above results show that the success message gets printed out, and no issues were found.

Congratulations

Congratulations, you have made it to the end of this tutorial!

In this tutorial, you've learned about type checking, different types of the type system in various languages with Python method('type()', and 'isinstance()') along with duck typing with Python and type hinting combined with 'mypy.'

If you would like to learn more about Python, take DataCamp's Software Engineering for Data Scientists in Python.

References:

  1. Corey's Youtube video Duck Typing